Saturday, January 22, 2011

ComboBox in WPF’s DataGrid through XAML

One thing I did recently was to allow user select value of a cell in WPF’s DataGrid from a ComboBox. I was using MVVM and the DataGrid was in my view so I had to define the columns and their bindings through XAML. After reading some articles on internet and some experimentation I was able to achieve the goal and I am sharing my solution here.

   1:  <DataGrid ItemsSource=”{Binding Path=CustomObjectCollection}” 
   2:   AutoGenerateColumns=”False>
   3:   <DataGrid.Columns>
   4:    <DataGridTemplateColumn>
   5:     <DataGridTemplateColumn.CellTemplate>
   6:      <DataTemplate>
   7:       <TextBlock Text=”{Binding Path=CustomObjectStringMember}”/>
   8:      </DataTemplate>
   9:     </DataGridTemplateColumn.CellTemplate>
  10:     <DataGridTemplateColumn.CellEditingTemplate >
  11:      <DataTemplate>
  12:       <ComboBox ItemsSource=”{Binding Path=CustomObjectListMember}” 
  13:       Text=”{Binding Path=CustomObjectStringMember}”/>
  14:      </DataTemplate>
  15:     </DataGridTemplateColumn.CellEditingTemplate>
  16:    </DataGridTemplateColumn>
  17:   </DataGrid.Columns>
  18:  </DataGrid>
In the code snippet above, CustomObjectCollection is an ObservableCollection where CustomObject is custom class I have written. Each instance of CustomObject in my ObservableCollection represents one row in my DataGrid. My CustomObject has two members ‘CustomObjectStringMember’ which is a String and ‘CustomObjectListMember’ which is List. The ComboBox in DataGrid will display the items in ‘CustomObjectListMember’ as possible options for selection and the selected value will be stored in ‘CustomObjectStringMember’ variable of my ‘CustomObject’ instance.

I have defined two templates inside XAML of my column. First one i.e. DataGridTemplateColumn.CellTemplate displays the selected value as TextBlock when the user is only viewing the the data in DataGrid. Second i.e. DataGridTemplateColumn.CellEditingTemplate will be activated when user will click on particular cell to edit its value. This template will update the cell from TextBlock to ComboBox and will allow user to select any value from the ComboBox. As soon as the cell will lose focus the CellTemplate will again replace the CellEditingTemplate

2 comments:

  1. Thank you for this. This is the most simple yet working solution for my problem I've found on the Internet.

    I've found that it is also possible to use compound objects for the list by using DisplayMemberPath and SelectedValuePath. This works since the displayed value is also the ID. It might also be possible to use paths for the value displayed, but I've not found any quick solution to that.

    Regards

    Snippet for my edition:

    ReplyDelete
  2. DataGridTemplateColumn.CellEditingTemplate >

    11:

    12:

    14:

    15:


    when i put all XAML UPER PORTION XAML SHOW ME ASSEMBLY REFERENCE ERROR

    ReplyDelete