Automatically edit Datagrid WPF content when datagrid-cell gets focus

I have a datagrid in WPF with DataGridTextColum and DataGridTemplateColum .

<DataGridTextColumn Width="4*" IsReadOnly="True" x:Name="dataGridColumnDescription" Header="Description" Binding="{Binding Description}"> </DataGridTextColumn> <DataGridTemplateColumn CellStyle="{StaticResource CellEditing}" IsReadOnly="False" Width="*" Header="Value" CellEditingTemplateSelector="{StaticResource myCellEditingTemplateSelectorValue}" CellTemplateSelector="{StaticResource myCellTemplateSelectorValue}"> </DataGridTemplateColumn> 

CellTemplateSelectors return a DataTemplate with a TextBlock for the Celltemplate, respectively. TextBox for CellEditing!

 <DataTemplate x:Key="dGridStringValueTemplate"> <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Path=Value}"/> </DataTemplate> <DataTemplate x:Key="dGridStringValueTemplateEditing"> <TextBox TextAlignment="Center" VerticalAlignment="Center" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" BorderThickness="1" Text="{Binding Path=Value, UpdateSourceTrigger=LostFocus}"/> </DataTemplate> 

Now I want to automatically focus the TextBox when the DataGridCell gets focus. The user should be able to edit the contents of the TextBox without double-clicking on the cell.

I found this article:

DataGrid Tips and Tricks: One-Click Editing Where can I get the current DataGridCell, but how can I access the content to give the text block the ability to edit the content?

This is my style:

 <Style x:Key="CellEditing" TargetType="{x:Type DataGridCell}"> <EventSetter Event="PreviewMouseLeftButtonDown" Handler="myDataGridMain_PreviewMouseLeftButtonDown"></EventSetter> </Style> 

This is my event handler:

 private void myDataGridMain_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { DataGridCell cell = sender as DataGridCell; // cell ist not null DataGridTemplateColumn col = cell.Column as DataGridTemplateColumn; //col is not null DataTemplate template = col.CellTemplate; //this is null } 

How can I get a text box with this event handler?

+8
c # wpf xaml datagrid
source share
4 answers

I did it, not the best solution, but it works ... When Cell gets focus, I set it to edit mode.

 private void myDataGridMain_OnFocus(object sender, RoutedEventArgs e) { DataGridCell cell = sender as DataGridCell; if (cell != null) cell.IsEditing = true; //var test = FindVisualChild<TextBlock>(cell); } 

In Keydown, I am looking for a visual child and give focus.

 private void myDataGridMain_KeyDown(object sender, KeyEventArgs e) { DataGridCell cell = sender as DataGridCell; if (e.Key == Key.Enter) { //give cell the focus cell.Focus(); } else { if ((cell != null)) { TextBox textbox = FindVisualChild<TextBox>(cell); if (textbox != null) { //TextBox has benn found if ((textbox as TextBox).IsFocused == false) { (textbox as TextBox).SelectAll(); } (textbox as TextBox).Focus(); } CheckBox chkbox = FindVisualChild<CheckBox>(cell); if (chkbox != null) { //Checkbox has been found (chkbox as CheckBox).Focus(); } ComboBox combbox = FindVisualChild<ComboBox>(cell); if (combbox != null) { //ComboBox has been found (combbox as ComboBox).Focus(); } } } } 

Find Visual Child!

 public static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) { DependencyObject child = VisualTreeHelper.GetChild(obj, i); if (child != null && child is T) return (T)child; else { T childOfChild = FindVisualChild<T>(child); if (childOfChild != null) return childOfChild; } } return null; } 
+2
source share

It works:

  <DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTemplateColumn> <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <TextBox FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"></TextBox> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid> 
+11
source share

This approach works for me. It uses the fact that the DataGrid will always create a new instance of the template when editing starts:

 <DataGridTemplateColumn.CellEditingTemplate> <DataTemplate> <TextBox Text="{Binding MyProperty}" Loaded="TextBox_Loaded"></TextBox> </DataTemplate> </DataGridTemplateColumn.CellEditingTemplate> 

and in the code behind:

 private void TextBox_Loaded(object sender, RoutedEventArgs e) { ((TextBox)sender).Focus(); ((TextBox)sender).SelectAll(); } 

As an added bonus, he also selects all the text in the cell. It should work no matter how you enter edit mode (double click, one click, press F2)

0
source share

simple answer for this creating a new control derived from datagrid control

  using System.Windows.Controls; public class CustomDataGrid : DataGrid { protected override void OnSelectedCellsChanged(SelectedCellsChangedEventArgs e) { //to make sure cell is selected var cells = e.AddedCells.FirstOrDefault(); if (cells != null) { this.BeginEdit(); } base.OnSelectedCellsChanged(e); } } 
0
source share

All Articles