Search code examples
c#wpftextboxtextblockdatagridcell

DataGridCell is a TextBlock when going down, but TextBox when going up


So, I have a DataGrid, which contains elements that look like this:

<DataGridTextColumn Header="Dto 1" Binding="{Binding Path=Dto1}">
    <DataGridTextColumn.EditingElementStyle>
        <Style TargetType="{x:Type TextBox}">
            <EventSetter Event="PreviewKeyDown" Handler="TextBox_PreviewKeyDown"/>
            <EventSetter Event="GotFocus" Handler="TextBox_GotFocus"/>
        </Style>
    </DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>

The PreviewKeyDown works perfectly fine, when I go up, I am able to get back to the cell with no problem. The way I see it, for all intents and purposes, I got a TextBox in there.

Now, when I try to go down from the cell in an event:

private void dgPropuestas_GotFocus(object sender, RoutedEventArgs e) {
        var cell = e.OriginalSource as DataGridCell;
        if (cell != null) {
            var cp = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(cell, 0), 0) as ContentPresenter;
            var tb = cp.Content as TextBlock;
            if (tb != null)
                tb.Focus();
        }
    }

(Note: I put the VisualTreeHelper method twice manually, I do have the FindVisualChildren one, but I went through the tree manually and as an act of desperation to speed up a bit, I put it manually)

If I try to declare tb as cp.Content as TextBox I get a null. For some reason, the ContentPresenter has inside a TextBlock, not a TextBox. FindVisualChildren(cell) returns an empty IEnumerable.

Why is this a problem? Because I need to be able to call SelectAll() on the text, and textBlock doesn't offer that option. Any help is greatly appreciated. Thanks in advance!

Later Edit: Apparently, when not in edit mode, the datagrid contains a textblock. When in edit mode, a textbox. Now, datagrid.BeginEdit() doesn't seem to work, as it doesn't initialize the TextBox nor does it trigger the event of PrepareCellForEditing.


Solution

  • Given that the TextBox would not get initialized with BeginEditing() nor with isEditing = true, the problem was fixed by declaring the fields as textbox and forcing them upon the datagrid:

    <DataGridTemplateColumn Header="Dto 2">
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBox Text="{Binding Dto2}" GotFocus="TextBox_GotFocus" PreviewKeyDown="TextBox_PreviewKeyDown"/>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>