Silverlight 2.0 Immersivity: Datagrid to ComboBox Data Binding

Our Silverlight 2.0 period of Immersivity today gives us the opportunity to work with ComboBoxes in our DataGrid.  The issues that need to be addressed are binding the correct value of the ComboBox-enabled column, binding a list to the ComboBox, and handling data updates.

Without further adieu we’ll go straight to the WOW! factor and display the latest version of my Silverlight 2.0 DataGrid app.  Pretty RAD, eh?

Before I “canvas” the broad-strokes on how to add a ComboBox to a DataGrid, let me give you the two main references I used going into today’s Silverlight Immersion Session, Manish Dalal’s “ComboBox in DataGrid” post and this Silverlight.Net forums thread.  Manish’s work is very instructive, but with real-world requirements of using data from a remote ASMX or WCF service, a slightly different approach is required.

Let’s start by adding the ComboBox Datagrid column in XAML.  Notice we’ll use a regular CellTemplate column to display the default value and a CellEditingTemplate to support the ComboBox.

<data:DataGridTemplateColumn Header=”Phase” Width=”260″>
    <data:DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <TextBlock Text=”{Binding Phase}” />
    </DataTemplate>
    </data:DataGridTemplateColumn.CellTemplate>
    <data:DataGridTemplateColumn.CellEditingTemplate>
    <DataTemplate>
        <src:MyComboBox SelectedItem=”{Binding Phase, Mode=TwoWay}”
              ItemsSource=”{Binding laborPhases}”
              DisplayMemberPath=”PhaseLong”
              SelectionChanged=”MyComboBox_SelectionChanged”
          Width=”260″  />
    </DataTemplate>
    </data:DataGridTemplateColumn.CellEditingTemplate>
</data:DataGridTemplateColumn>

I’m using a custom MyComboBox class because of an apparent bug in how the ComboBox doesn’t stay open.  The code is on Manish’s post.  Another point is that I’m displaying the cell content (the Job Phase) directly from the DataGrid data source and not using a Key lookup value to display the item from the Job Phase list.  It’s also noteworthy that the default text display is a TextBLOCK, not TextBOX.  A PreparingCellForEdit event is used to populate the ComboBox.  The XAML:

<data:DataGrid x:Name=”dg” AutoGenerateColumns=”False” Grid.Row=”0″
         BeginningEdit=”dg_BeginningEdit” PreparingCellForEdit=”dg_PreparingCellForEdit”>

The CodeBehind:

private void dg_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
{
    if ((string)dg.CurrentColumn.Header == “Phase”)
    {
         MyComboBox phases = (MyComboBox)dg.CurrentColumn.GetCellContent(e.Row);
         phases.ItemsSource = laborPhases;  //retrieved from a Web Service
         phases.SelectedIndex = 0;
    }
}

Why “phases.SelectedIndex = 0;” you ask?  Because I couldn’t set a default property in the list when the ComboBox opened.  I tried with the DropDownOpen event and variants of the above.  I think it may be the behavior of the Silverlight 2.0 ComboBox, but if I figure out how to set a default value I’ll let you know.  At least SelectedIndex highlighted something.

If you remember yesterday’s session, we’re using a currentLaborPost record to hold the current edited record, which we set in the DataGrid BeginningEdit event.

private void dg_BeginningEdit(object sender, DataGridBeginningEditEventArgs e)
{
    LaborPost _laborPost = (LaborPost)dg.SelectedItem as LaborPost;
    currentLaborPost = _laborPost;
}

On the ComboBox update we refresh the currentLaborPost and the changed LaborPost Collection that we’ll be sending back to the Web Service.

private void MyComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    LaborPhase phase = ((LaborPhase)e.AddedItems[0]);
    currentLaborPost.PhaseID = phase.PhaseID;
    currentLaborPost.Phase = phase.PhaseLong;
    UpdateChangedCollection();
}

Next up is adding and deleting records to the DataGrid.  Can’t wait!

Article written by

A long time developer, I was an early adopter of Linux in the mid-90's for a few years until I entered corporate environments and worked with Microsoft technologies like ASP, then .NET. In 2008 I released Sueetie, an Online Community Platform built in .NET. In late 2012 I returned to my Linux roots and locked in on Java development. Much of my work is available on GitHub.