Binding a combo box to a lookup table with VS2010b2 RIA

Assume your model looks like this, and you compiled and generated a DomainDataSource from it. Compile again and drag both entities onto the form. This will make the designer put all the necessary references and whatnot in place. Delete the data grid that was generated for EmployeeGroup; you don’t need it, you just wanted the designer to write your declarations and associated initialisation code. At this point, both employeeDomainDataSource and employeeGroupDomainDataSource will be in scope in your XAML.

Model

Targeting Silverlight 3

Create a class EmployeeGroupValueConverter in the Helpers folder of your Silverlight project. You will have to edit the namespace to remove “.Helpers”. The code should look like this:

    1 using System;

    2 using System.Linq;

    3 using System.Windows.Controls;

    4 using System.Windows.Data;

    5 using BusinessApplication1.Web.Models;

    6 

    7 namespace BusinessApplication1

    8 {

    9   public class EmployeeGroupValueConverter : IValueConverter

   10   {

   11     public static DomainDataSource ItemsSource { get; set; }

   12 

   13     #region IValueConverter Members

   14 

   15     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

   16     {

   17       if (ItemsSource == null)

   18         return Guid.Empty;

   19       else

   20         return ItemsSource.Data.Cast<EmployeeGroup>().First(item => item.Id == (Guid)value);

   21     }

   22 

   23     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

   24     {

   25       if (value == null)

   26         return null;

   27       else

   28         return (value as EmployeeGroup).Id;

   29     }

   30 

   31     #endregion

   32   }

   33 }

Earlier you dropped the EmployeeGroupDomainDataSource on the design surface causing the following to be generated. Note the fact that a handler has already been generated for the DDS LoadedData event.

    9   <riaControls:DomainDataSource

   10     AutoLoad="True" Height="0"

>> 11     LoadedData="employeeGroupDomainDataSource_LoadedData"

   12     Name="employeeGroupDomainDataSource"

   13     QueryName="GetEmployeeGroupsQuery" Width="0">

   14     <riaControls:DomainDataSource.DomainContext>

   15       <my:DomainService1 />

   16     </riaControls:DomainDataSource.DomainContext>

   17   </riaControls:DomainDataSource>

This provides a good hook for populating the static property ItemSource of the value converter class.

   32     private void employeeGroupDomainDataSource_LoadedData(object sender, LoadedDataEventArgs e)

   33     {

>> 34       EmployeeGroupValueConverter.ItemsSource = sender as DomainDataSource;

   35       if (e.HasError)

   36       {

   37         MessageBox.Show(e.Error.ToString(), "Load Error", MessageBoxButton.OK);

   38         e.MarkErrorAsHandled();

   39       }

   40     }

The value conversion is required because the SelectedItem property of the combo box returns a collection item, which in this case is an EmployeeGroup object. The value converter simply converts between the FK value and the corresponding EmployeeGroup object, making the following binding legal. Line 86 is where the rubber meets the road.

   83           <ComboBox Grid.Column="1" Grid.Row="6" Height="23" HorizontalAlignment="Left"

   84                     DisplayMemberPath="GroupName"

   85                     ItemsSource="{Binding ElementName=employeeGroupDomainDataSource, Path=Data}"

>> 86                     SelectedItem="{Binding EmployeeGroupId, Mode=TwoWay, Converter={StaticResource EmployeeGroupValueConverter}}"

   87                     Margin="3" Name="employeeGroupIdComboBox" VerticalAlignment="Center" Width="120">

   88             <ComboBox.ItemsPanel>

   89               <ItemsPanelTemplate>

   90                 <VirtualizingStackPanel />

   91               </ItemsPanelTemplate>

   92             </ComboBox.ItemsPanel>

   93           </ComboBox>

It’s not completely declarative, but it’s close. This works in both data grids and data forms.

Targeting Silverlight 4

Oh happy day! No code required! SelectedValue and SelectedValuePath are finally supported! Just declare it like this:

   95           <ComboBox Grid.Column="1" Grid.Row="6" Height="23" HorizontalAlignment="Left"

   96             DisplayMemberPath="GroupName"

   97             ItemsSource="{Binding ElementName=employeeGroupDomainDataSource, Path=Data}"

>> 98             SelectedValue="{Binding EmployeeGroupId, Mode=TwoWay}"

>> 99             SelectedValuePath="Id"

  100             Margin="3" Name="employeeGroupIdComboBox" VerticalAlignment="Center" Width="120">

  101             <ComboBox.ItemsPanel>

  102               <ItemsPanelTemplate>

  103                 <VirtualizingStackPanel />

  104               </ItemsPanelTemplate>

  105             </ComboBox.ItemsPanel>

  106           </ComboBox>

Published 12-10-2009 15:53 by peterw