WPF DataGrid DataGridRow覆盖ItemsPanel中断Tab键顺序

时间:2017-03-23 00:42:15

标签: c# wpf datagrid tab-ordering itemspanel

我正在开发一个需要在窗口内展开和收缩的2D网格的WPF项目。为了做到这一点,我已经使用UniformGrids替换了DataGrid中的ItemsPanels。当我这样做时,控件会正确扩展和收缩。

不幸的是,由于某些原因,这会破坏DataGrid中的Tab键顺序。如果按Tab键,它将下拉一行而不是直接跳到下一列。当标签点击行的末尾时,它将转到下一列的顶部并继续向下。左,右,上,下箭头键均按预期工作,唯一受影响的功能是Tab键顺序。如果我删除DataGridRow样式,Tab键顺序将自行更正,但行不会随窗口一起展开。

这个问题似乎与UniformGrid无关,因为StackPanel也会产生相同的制表符症状。

是否有人知道我应该如何或者应该寻找什么来修复此标签问题,或者可能采用其他方式使网格根据需要进行扩展和收缩?

示例XAML:

<Window x:Class="SODatagridSample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <Style TargetType="{x:Type DataGridRow}">
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <UniformGrid IsItemsHost="True" Rows="1" />
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
    <Grid>
        <DataGrid x:Name="datagrid" ItemsSource="{Binding Values}" SelectionMode="Extended"  SelectionUnit="Cell" ColumnWidth="*" HeadersVisibility="None"
                  CanUserAddRows="False" CanUserDeleteRows="False">
            <DataGrid.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Columns="1"></UniformGrid>
                </ItemsPanelTemplate>
            </DataGrid.ItemsPanel>
        </DataGrid>
    </Grid>
</ScrollViewer>

背后的示例代码:

using System.ComponentModel;
using System.Data;
using System.Windows;

namespace SODatagridSample
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public DataTable Values
        {
            get { return _Values; }
            set
            {
                _Values = value;
                OnPropertyChanged(nameof(Values));
            }
        }
        private DataTable _Values;

        public MainWindow()
        {
            Values = new DataTable();

            for (int i = 0; i < 15; i++)
                Values.Columns.Add(i.ToString(), typeof(double));

            for (int i = 0; i < 10; i++)
                Values.Rows.Add(Values.NewRow());

            for (int x = 0; x < 10; x++)
                for (int y = 0; y < 15; y++)
                    Values.Rows[x][y] = x * 15 + y;

            DataContext = this;
            InitializeComponent();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string name)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }
}

1 个答案:

答案 0 :(得分:0)

修复非常简单。反映出DataGridCellPanel之后,我注意到它有以下静态构造函数:

static DataGridCellsPanel()
        {
            KeyboardNavigation.TabNavigationProperty.OverrideMetadata(typeof(DataGridCellsPanel), new FrameworkPropertyMetadata((object)KeyboardNavigationMode.Local));
        }

所需要的只是扩展UniformGrid以添加静态构造函数,或者只是将附加属性KeyboardNavigation.TabNavigation =“Local”添加到DataGridRow样式的UniformGrid中:

        <Style TargetType="{x:Type DataGridRow}">
            <Setter Property="ItemsPanel">
                <Setter.Value>
                    <ItemsPanelTemplate>
                        <UniformGrid KeyboardNavigation.TabNavigation="Local" IsItemsHost="True" Rows="1"/>
                    </ItemsPanelTemplate>
                </Setter.Value>
            </Setter>
        </Style>