I experienced some frustration with lack of other examples on getting select boxes to work on WPF DataGrid.
The first problem I encountered was that combo boxes did not have single-click to edit. That's what the Setter
s are for.
The next problem was that once I selected an item in a combobox, the combobox would not leave edit mode if I clicked directly into the next row. That's what the LostFocus
and GotFocus
events fix.
<!-- XAML -->
<DataGridComboBoxColumn
ItemsSource="{Binding Source=Blah}"
Header="Example"
DisplayMemberPath="Example"
SelectedValuePath="Id"
SelectedValueBinding="{Binding Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Path=Example}">
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<EventSetter Event="LostFocus" Handler="ComboBox_LostFocus"/>
<EventSetter Event="GotFocus" Handler="ComboBox_GotFocus" />
<Setter Property="IsEditable" Value="False" />
<Setter Property="IsSynchronizedWithCurrentItem" Value="False" />
<Setter Property="IsDropDownOpen" Value="True" />
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
// C# codebehind. Put these in your XAML code-behind class.
private void ComboBox_GotFocus(object sender, RoutedEventArgs e)
{
if(sender == e.OriginalSource)
{
var cb = sender as ComboBox;
cb.DropDownClosed -= ComboBox_DropDownClosed;
cb.DropDownClosed += ComboBox_DropDownClosed;
}
}
private void ComboBox_DropDownClosed(object sender, EventArgs e)
{
DataGrid grid = DataGridHelper.FindVisualParent<DataGrid>(sender as ComboBox);
if (grid == null)
return;
grid.CommitEdit();
}
private void ComboBox_LostFocus(object sender, RoutedEventArgs e)
{
if (sender == e.OriginalSource)
{
var cb = sender as ComboBox;
cb.DropDownClosed -= ComboBox_DropDownClosed;
}
}
Thanks for posting this. Exactly what I was looking for to make combo columns feel more intuitive.