binding combox in wpf datagrid

2020-02-15 15:29发布

问题:

I have a list that I populate in the init of my viewmodel:

ListOfEmployees = new List<EmployeeBO>(employeeRepository.GetEmployees(true, true));

I am trying to get a combobox in a datagrid to populate from this list.

<DataGridTemplateColumn Header="U/M" MinWidth="145">
 <DataGridTemplateColumn.CellEditingTemplate>
  <DataTemplate>
   <ComboBox Name="cboUnitMeasure" 
     ItemsSource="{Binding Path=ListOfUnitMeasures}"
     DisplayMemberPath="UnitMeasureDescription" SelectedValuePath="UnitMeasureValue" 
     SelectedValue="{Binding UnitMeasureValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
     HorizontalAlignment="Left" Width="140" />
  </DataTemplate>
 </DataGridTemplateColumn.CellEditingTemplate>
 <DataGridTemplateColumn.CellTemplate>
  <DataTemplate>
   <TextBlock Text="{Binding UnitMeasureDescription}" />
  </DataTemplate>
 </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

When the dg loads, the cell template displays the UnitMeasureDescription value, but when I click on the cell to edit, there are no items in the combobox. On the other hand, when I use a static resource from an xml file as the itemsource-using the same property names-the combobox contains the items:

<DataGridTemplateColumn Header="U/M" MinWidth="145">
 <DataGridTemplateColumn.CellEditingTemplate>
  <DataTemplate>
   <ComboBox Name="cboUnitMeasure" 
     ItemsSource="{Binding Source={StaticResource UnitMeasureData}}"
     DisplayMemberPath="UnitMeasureDescription" SelectedValuePath="UnitMeasureValue" 
     SelectedValue="{Binding UnitMeasureValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
     HorizontalAlignment="Left" Width="140" />
  </DataTemplate>
 </DataGridTemplateColumn.CellEditingTemplate>
 <DataGridTemplateColumn.CellTemplate>
  <DataTemplate>
   <TextBlock Text="{Binding UnitMeasureDescription}" />
  </DataTemplate>
 </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

I put a breakpoint just after populating ListOfEmployees in my vm and it contains items. I also verified the property names in the DisplayMemberPath and SelectedValuePath are correct. Not sure what I am doing wrong here.

回答1:

Is "ListOfUnitMeasures" a property on the VM or a property of an EmployeeBO? Ok, assuming that the DataGrid's ItemsSource is set to the List<EmployeeBO> and that there's another list on the VM called "ListUnitOfMeasures", here's my explanation:

The DataContext of each row in the DataGrid will be equal to the elements in the DataGrid's ItemsSource. In your case, each row will use an EmployeeBO as its DataContext. And since the "ListOfUnitMeasures" isn't a property of Employee BO, the Binding on the ComboBox will not work and thus won't display anything.

One possible solution is change the Binding on your ComboBox to use a RelativeSource pointing back to the parent DataGrid as follows:

<ComboBox Name="cboUnitMeasure" 
     ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.ListOfUnitMeasures}"/>