Monday, May 6, 2013

MultiColumn ComboBox in WPF DataGrid

Recently one of the user on MSDN forum wanted to have MultiColumn ComboBox in WPF DataGrid. Although there are many articles for creating Simple MultiColumn Combobox but not many article for having it inside Datagrid. So I decided to write a small snippet which can work for Datagrid.
 
DataGrid has DataGridTemplateColumn where we can host a Control. So to show Multi Column ComboBox in dropdown area, we can change the style of ComboBox as in below code.
<DataGrid x:Name="DGOrders" Margin="30" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding OrderID}" Header="Order ID" />
<DataGridTemplateColumn Header="User" Width="200">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedValue="{Binding UserID}" SelectedValuePath="UserID" DisplayMemberPath="CompanyName" HorizontalContentAlignment="Stretch" ItemsSource="{Binding}" >
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Margin="5" Grid.Column="0" Text="{Binding UserID}"/>
<TextBlock Margin="5" Grid.Column="1" Text="{Binding CompanyName}"/>
<TextBlock Margin="5" Grid.Column="2" Text="{Binding UserName}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>






In this example, we are changing the style by setting ItemContainerStyle property of ComboBox. So now when dropdown for ComboBox will get open, we will see UserID, CompanyName and UserName details. Here ComboBox selection will show what we have set in DisplayMemberPath like in following image

Example1

Another way to have MultiColumn is to change ItemTemplate of ComboBox and display result from multiple columns.

        <DataGrid x:Name="DGOrders" Margin="30" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding OrderID}" Header="Order ID" />
<DataGridTemplateColumn Header="User" Width="200">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedValue="{Binding UserID}" SelectedValuePath="UserID" HorizontalContentAlignment="Stretch" ItemsSource="{Binding}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<TextBlock Margin="5" Grid.Column="0" Text="{Binding UserID}"/>
<TextBlock Margin="5" Grid.Column="1" Text="{Binding CompanyName}"/>
<TextBlock Margin="5" Grid.Column="2" Text="{Binding UserName}"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>




In this example, we are changing the ItemTemplate, so now we will see UserID, CompanyName and UserName details in ComboBox Selection and Dropdown result as in following image.

Example2

Now when you have a requirement of showing Multiple Column in DataGridColumn you can try one of the above two methods.

Another way to show Multiple Column in DataGridColumn is to host a DataGrid in DataGridTemplateColumn. I will have an example of it in one of my future articles.