【问题标题】:Set Focus to DataGridTemplateColumn Child control when pressing enter按下回车键时将焦点设置为 DataGridTemplateColumn 子控件
【发布时间】:2018-01-06 00:13:19
【问题描述】:

我有一个Datagrid 和一个DataGridTemplateColumn,其中有一个TextBox。当焦点在文本框中并且我按 Enter 键转到下一条记录时,它专注于 DataGridTemplateColumn 而不是子文本框,迫使我按 Tab 进入文本框。我发现这段代码可以在列中使用选项卡,效果非常好,但是当我按 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>

这是我的DataGridTemplateColumn 代码:

<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>

我已尝试禁用 FocusableIsHitTestVisible,但这些不是我需要的。我也玩过其他几个KeyboardNavigation 设置,但还没有让它工作。必须有一种方法来实现这一点,但我没有找到它的运气。基本上我想完全绕过DataGridTemplateColumn,只允许关注子控件。这可能吗?

【问题讨论】:

    标签: c# wpf xaml mvvm datagrid


    【解决方案1】:

    添加这个附加的属性类

    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;
            }
        }
    }
    

    并为 DataGridCell 设置样式

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

    【讨论】:

    • 效果很好,谢谢。我确实必须将FocusNavigationDirection.Next 更改为FocusNavigationDirection.Down 才能正常工作。它将焦点在同一记录中向右移动,而不是向下移动到下一条记录。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    • 2014-08-04
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多