DataGridComboBoxColumn - one-click auto shutdown

I have a DataGridComboBoxColum in a DataGrid. I would like to be able to click on a cell once and release the dropdowns. Currently, I have to click several times.

<DataGrid AutoGenerateColumns="False" Height="148" HorizontalAlignment="Left" Margin="48,85,0,0" Name ="dg_display" VerticalAlignment="Top" Width="645" CanUserAddRows="False" CanUserDeleteRows="False" ItemsSource="{Binding}" SelectionChanged="DgDisplaySelectionChanged"> <DataGrid.Columns> <DataGridTextColumn IsReadOnly="True" Header="Symbol" Binding="{Binding Symbol}" /> <DataGridTextColumn IsReadOnly="True" Header="Company ID" Binding="{Binding CompanyID}" /> <DataGridComboBoxColumn IsReadOnly="False" Header="Sector" SelectedValueBinding="{Binding Sector}" DisplayMemberPath="{Binding [0]}" Visibility="Visible" > <DataGridComboBoxColumn.EditingElementStyle> <Style TargetType="ComboBox"> <Setter Property="ItemsSource" Value="{Binding SectorList}" /> </Style> </DataGridComboBoxColumn.EditingElementStyle> <DataGridComboBoxColumn.ElementStyle> <Style TargetType="ComboBox"> <Setter Property="ItemsSource" Value="{Binding SectorList}" /> </Style> </DataGridComboBoxColumn.ElementStyle> </DataGridComboBoxColumn> </DataGrid.Columns> </DataGrid> 
+8
source share
3 answers

One-click editing of a DataGridComboBoxColumn + one-click CheckboxColumn
See also: http : //stackoverflow.com

XAML:

  <Style TargetType="{x:Type DataGridCell}"> <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridCell_PreviewMouseLeftButtonDown" /> <EventSetter Event="PreviewTextInput" Handler="DataGridCell_PreviewTextInput" /> </Style> 

Code for:

  private void DataGridCell_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { DataGridCell cell = sender as DataGridCell; GridColumnFastEdit(cell, e); } private void DataGridCell_PreviewTextInput(object sender, TextCompositionEventArgs e) { DataGridCell cell = sender as DataGridCell; GridColumnFastEdit(cell, e); } private static void GridColumnFastEdit(DataGridCell cell, RoutedEventArgs e) { if (cell == null || cell.IsEditing || cell.IsReadOnly) return; DataGrid dataGrid = FindVisualParent<DataGrid>(cell); if (dataGrid == null) return; if (!cell.IsFocused) { cell.Focus(); } if (cell.Content is CheckBox) { if (dataGrid.SelectionUnit != DataGridSelectionUnit.FullRow) { if (!cell.IsSelected) cell.IsSelected = true; } else { DataGridRow row = FindVisualParent<DataGridRow>(cell); if (row != null && !row.IsSelected) { row.IsSelected = true; } } } else { ComboBox cb = cell.Content as ComboBox; if (cb != null) { //DataGrid dataGrid = FindVisualParent<DataGrid>(cell); dataGrid.BeginEdit(e); cell.Dispatcher.Invoke( DispatcherPriority.Background, new Action(delegate { })); cb.IsDropDownOpen = true; } } } private static T FindVisualParent<T>(UIElement element) where T : UIElement { UIElement parent = element; while (parent != null) { T correctlyTyped = parent as T; if (correctlyTyped != null) { return correctlyTyped; } parent = VisualTreeHelper.GetParent(parent) as UIElement; } return null; } 
+8
source

I'm having trouble with @surfen's answer, probably because it is many years later, and WPF probably changed a bit. It seems that DataGrid now takes care of some things for you, for example, it automatically edits a text field when you start typing.

I use a DataGridTemplateColumn for a combo column. The template has a TextBlock for its CellTemplate . A BeginEdit call, followed by a dispatcher call, invokes a combo box in the visual tree. Then a message appears that the mouse click is sent to the combo box and opens by itself.

Here is my modified version of @surfen code:

 public static class DataGridExtensions { public static void FastEdit(this DataGrid dataGrid) { dataGrid.ThrowIfNull(nameof(dataGrid)); dataGrid.PreviewMouseLeftButtonDown += (sender, args) => { FastEdit(args.OriginalSource, args); }; } private static void FastEdit(object source, RoutedEventArgs args) { var dataGridCell = (source as UIElement)?.FindVisualParent<DataGridCell>(); if (dataGridCell == null || dataGridCell.IsEditing || dataGridCell.IsReadOnly) { return; } var dataGrid = dataGridCell.FindVisualParent<DataGrid>(); if (dataGrid == null) { return; } if (!dataGridCell.IsFocused) { dataGridCell.Focus(); } if (dataGridCell.Content is CheckBox) { if (dataGrid.SelectionUnit != DataGridSelectionUnit.FullRow) { if (!dataGridCell.IsSelected) { dataGridCell.IsSelected = true; } } else { var dataGridRow = dataGridCell.FindVisualParent<DataGridRow>(); if (dataGridRow != null && !dataGridRow.IsSelected) { dataGridRow.IsSelected = true; } } } else { dataGrid.BeginEdit(args); dataGridCell.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() => { })); } } } public static class UIElementExtensions { public static T FindVisualParent<T>(this UIElement element) where T : UIElement { UIElement currentElement = element; while (currentElement != null) { var correctlyTyped = currentElement as T; if (correctlyTyped != null) { return correctlyTyped; } currentElement = VisualTreeHelper.GetParent(currentElement) as UIElement; } return null; } } 
+2
source

None of the other answers worked for me. Which worked for me, although there was the following.

 <DataGridComboBoxColumn Header="Example ComboBox" DisplayMemberPath="Name" SelectedValuePath="Id"> <DataGridComboBoxColumn.EditingElementStyle> <Style TargetType="ComboBox"> <Setter Property="IsDropDownOpen" Value="True" /> </Style> </DataGridComboBoxColumn.EditingElementStyle> </DataGridComboBoxColumn> 

I do not remember where I got this solution. Perhaps this was due to. If someone sees the original source, feel free to leave comments.

0
source

All Articles