WPF binding a ComboBox embedded in DataGridTemplateColumn to a DataTable

543 views Asked by At

I have a DataGrid whose DataContext is set (in C# code) to a DataTable so that each column in the DataGrid is bound to a column in the DataTable. In one column of the DataGrid I want to display an editable ComboBox that offers options that are pulled from a MySQL database and stored in another DataTable. This DataTable is provided using ObjectDataProvider and is being filled properly (I traced this using the debugger). However the problem is that the ComboBox in the DataGrid displays only those items that are in both the DataTable and already in other cells in that same column. How can I get the ComboBox to display the complete list of items retrieved from the DataTable?

Here are the relevant bits of code.

The ObjectDataProvider that provides the DataTable for the ComboBox is:

    <ObjectDataProvider x:Key="AbodesTable"
        ObjectType="{x:Type local:DatabaseTable}"
        MethodName="GetTable">
        <ObjectDataProvider.MethodParameters>
            <s:String>SELECT * FROM abode</s:String>
            <s:String>AbodeName</s:String>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>

The DatabaseTable class just sends the query to the MySQL database and fills and returns the DataTable and is working correctly.

The DataGrid is:

    <DataGrid x:Name="baptismDataGrid" Margin="0" Grid.Row="1" AutoGenerateColumns="False"
              IsReadOnly="False" ItemsSource="{Binding}" SelectionMode="Single"
              RowEditEnding="transcriptDataGrid_RowEditEnding" 
              KeyUp="transcriptDataGrid_KeyUp">
              <DataGrid.Columns>
              .....<!-- Other columns -->
              <DataGridTemplateColumn x:Name="AbodeColumn" Header="Abode">
                  <DataGridTemplateColumn.CellTemplate>
                      <DataTemplate>
                         <TextBlock Text="{Binding Abode}"></TextBlock>
                      </DataTemplate>
                   </DataGridTemplateColumn.CellTemplate>
                   <DataGridTemplateColumn.CellEditingTemplate>
                      <DataTemplate>
                         <ComboBox ItemsSource="{Binding Source={StaticResource AbodesTable} }" IsEditable="True"
                                 Text="{Binding Abode}" 
                                 DisplayMemberPath="AbodeName" 
                                 SelectedValuePath="AbodeName">
                          </ComboBox>
                        </DataTemplate>
                      </DataGridTemplateColumn.CellEditingTemplate>
                    </DataGridTemplateColumn>
                  </DataGrid.Columns>
                </DataGrid>

The binding to "Abode" binds the text in the ComboBox to the Abode column in the DataTable that is the DataContext for the DataGrid. AbodeName is the name of the column in the DataTable to which the ComboBox is bound.

The problem is that the ComboBox contains only those items from the AbodesTable static resource that are found in the existing cells of the Abode column in the DataGrid. (In other words, in set terminology, the ComboBox contains the intersection of those elements in AbodesTable and the set of entries in the Abode column in the DataGrid.) I would like the ComboBox to contain all the items in the AbodesTable, regardless of whether they already appear in the DataGrid.

Apart from this problem, the program works properly, in that something entered into the Abode column either by selecting from the ComboBox or just typing in some text is properly bound to the underlying DataTable, so the DataTable can be written back to the MySQL database.

Thanks for any help or suggestions.

1

There are 1 answers

0
G. Rowe On

I've solved this by converting the desired column in the DataTable to a List<string> and using that as the ItemsSource for the ComboBox. The ComboBox in the DataGridTemplateColumn above now looks like this:

     <ComboBox ItemsSource="{Binding Source={StaticResource AbodesList}}" 
               IsEditable="True" Text="{Binding Abode}">
     </ComboBox>

The StaticResource AbodesList refers to an ObjectDataProvider which queries the MySQL database and converts the desired column to a List<string>.