R. Roe
R. Roe

Reputation: 609

Set Focus to DataGridTemplateColumn Child control when pressing enter

I have a Datagrid with a DataGridTemplateColumn that has a TextBox in it. When the focus is in the textbox and I press enter to go to the next record it focuses on the DataGridTemplateColumn instead of the child textbox forcing me to press Tab to enter the textbox. I found this code that works with tabbing into the column that works fabulously, but I can't get the same functionality when I press Enter.

<Style x:Key="columnTabStop" TargetType="{x:Type DataGridCell}">
    <Setter Property="KeyboardNavigation.IsTabStop" Value="False" />
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="KeyboardNavigation.IsTabStop" Value="True" />
        </Trigger>
    </Style.Triggers>
</Style>

Here is my DataGridTemplateColumn code:

<DataGridTemplateColumn Header="Weld Time" CellStyle="{StaticResource columnTabStop}">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBox Text="{Binding DataContext.WeldTime,RelativeSource={RelativeSource AncestorType=DataGridRow}}" 
                 BorderThickness="0" BorderBrush="Transparent" Background="BlanchedAlmond" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

I've tried disabling Focusable and IsHitTestVisible but those aren't what I need. I've also played with several of the other KeyboardNavigation settings but haven't gotten it to work. There's got to be a way of achieving this, but I haven't had any luck finding it. Basically I want to bypass the DataGridTemplateColumn entirely only allowing focus to the child control. Is this possible?

Upvotes: 1

Views: 957

Answers (1)

cuongtd
cuongtd

Reputation: 3182

Add this attached property class

public class EnterKeyTraversal
{
    public static bool GetIsEnabled(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsEnabledProperty);
    }

    public static void SetIsEnabled(DependencyObject obj, bool value)
    {
        obj.SetValue(IsEnabledProperty, value);
    }

    static void ue_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        var ue = e.OriginalSource as FrameworkElement;

        if (e.Key == Key.Enter)
        {
            e.Handled = true;
            ue.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
        }
    }

    private static void ue_Unloaded(object sender, RoutedEventArgs e)
    {
        var ue = sender as FrameworkElement;
        if (ue == null) return;

        ue.Unloaded -= ue_Unloaded;
        ue.PreviewKeyDown -= ue_PreviewKeyDown;
    }

    public static readonly DependencyProperty IsEnabledProperty =
        DependencyProperty.RegisterAttached("IsEnabled", typeof(bool),

        typeof(EnterKeyTraversal), new UIPropertyMetadata(false, IsEnabledChanged));

    static void IsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var ue = d as FrameworkElement;
        if (ue == null) return;

        if ((bool)e.NewValue)
        {
            ue.Unloaded += ue_Unloaded;
            ue.PreviewKeyDown += ue_PreviewKeyDown;
        }
        else
        {
            ue.PreviewKeyDown -= ue_PreviewKeyDown;
        }
    }
}

and set style for DataGridCell

  <Style TargetType="{x:Type DataGridCell}">
        <Setter Property="local:EnterKeyTraversal.IsEnabled" Value="True"/>
  </Style>

Upvotes: 2

Related Questions