按下Enter键

时间:2018-05-24 21:37:01

标签: c# wpf focus

我有一个包含很多列的数据网格。现在通常用户可以按TAB在DataGrid单元格中的控件之间循环。数据网格单元格已设置为IsTabStop = false,因此它会跳过聚焦于单元格本身,并且直到焦点集中在实际控件上才会跳过。

如果用户按Enter键,这似乎不起作用,因为他们想在同一列中工作。 DataGrid会将焦点传递给COLUMN中的下一个单元格,但它也会忽略IsTabStop设置,因此它只关注单元格而不是内部控件。

任何想法如何解决这个问题。

简短的例子

<DataGrid AutoGenerateColumns="False" Name="grid1" >
    <DataGrid.Resources>
        <Style TargetType="{x:Type Border}" x:Key="coloredBorder">
            <Setter Property="Background" Value="Yellow"/>
        </Style>
        <Style TargetType="DataGridCell">
            <Setter Property="IsTabStop" Value="False"/>
        </Style>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding A, Mode=OneWay}" Header="A"/>
        <DataGridTemplateColumn Header="B">
            <DataGridTemplateColumn.CellStyle>
                <Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource {x:Type DataGridCell}}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type DataGridCell}">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition/>
                                    </Grid.ColumnDefinitions>
                                    <Border BorderBrush="Black" BorderThickness="0,0,1,0" Width="20" Height="20" Style="{DynamicResource coloredBorder}"/>
                                    <ComboBox Grid.Column="1" SelectedItem="{Binding A, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                                                ItemsSource="{Binding MenuItems, ElementName=window}"></ComboBox>
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </DataGridTemplateColumn.CellStyle>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

此外,我已为此here添加了示例WPF应用。要重现,请抓住其中一个组合框以使其聚焦。 Pres选项卡,您将看到下一个组合框正常获得焦点。如果我添加了多个组合框列,右侧的组合框将获得焦点。

但如果按Enter键,焦点将转到下面的单元格,但它不会跳过单元格并转到单元格内容。而是突出显示单元格。 像这样:

enter image description here

1 个答案:

答案 0 :(得分:0)

基于reply I got on MSDN

我通过制作附属物来解决这个问题:

using System.Windows;
using System.Windows.Input;

namespace GridTabbing
{
    public class EnterKeySample
    {
        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.Down));
            }
        }

        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(EnterKeySample), 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;
            }
        }
    }
}

奇怪的是,这是唯一要做的就是告诉WPF在用户按Enter键时将焦点传递给DOWN,我认为这已经发生了,但显然不是。

相关问题