Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatic editing of WPF datagrid content when datagrid-cell gets focus

I have a datagrid in WPF with a DataGridTextColum and a 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>

The CellTemplateSelectors return a DataTemplate with a TextBlock for the the Celltemplate resp. a 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 the focus. The user should be able to edit the TextBox content without doubleclicking the cell.

I found this article:

DataGrid Tips & Tricks: Single-Click Editing where I can get the Current DataGridCell, but how can I access the content to give the Textbox the focus 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 the textbox with that event handler?

like image 814
nullxff Avatar asked Jan 27 '15 10:01

nullxff


People also ask

How to make DataGrid editable in WPF?

By default, you can edit items directly in the DataGrid. The user can enter edit mode in a cell by pressing F2 key or double tapping on a cell. Alternatively, you can set the DataGridColumn. IsReadOnly property to true to disable editing in specific columns of the DataGrid.

How to make DataGrid column editable in WPF?

Set AutoGenerateColumns="False" on the DataGrid and set IsReadOnly="True" for all columns except the column you want to be editable you will set IsReadOnly="False".

How to change DataGrid cell value in WPF?

You can select multiple cells by setting SelectionUnit as Cell or Any and SelectionMode as Multiple or Extended in WPF DataGrid (SfDataGrid). You can edit and change the value of all the selected cells when editing completes by handling SfDataGrid. CurrentCellEndEdit event.


2 Answers

This seems to work :

    <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>
like image 192
eran otzap Avatar answered Sep 21 '22 07:09

eran otzap


This approach works for me. It uses the fact that the DataGrid will always create a new instance of the template when the 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, it also selects all text in the cell. It should work no matter how you enter the editing mode (double click, single click, pressing F2)

like image 30
vesan Avatar answered Sep 19 '22 07:09

vesan