简体   繁体   English

WPF DataGrid DataGridRow覆盖ItemsPanel中断选项卡顺序

[英]WPF DataGrid DataGridRow override ItemsPanel breaks tab order

I am working on a WPF project that needs a 2D grid that needs to expand and contract within a window. 我正在一个WPF项目中,该项目需要一个2D网格,该网格需要在窗口内扩展和收缩。 In order to do this I have replaced the ItemsPanels within the DataGrid with UniformGrids. 为此,我用UniformGrids替换了DataGrid中的ItemsPanels。 When I do this, the control expands and contracts correctly. 当我这样做时,控件将正确展开和收缩。

Unfortunately, for some reason this breaks the tab order within the DataGrid. 不幸的是,由于某种原因,这破坏了DataGrid中的选项卡顺序。 If you press tab, it will drop down a row rather than jump right to the next column. 如果按Tab键,它将下拉一行,而不是跳到下一列。 When the tab hits the end of the row, it will go to the top of the next column and continue down it. 当选项卡到达行尾时,它将转到下一列的顶部并继续向下。 The left,right,up,down arrow keys all work as expected, the only functionality affected is the tab order. 左,右,上,下箭头键均按预期工作,受影响的唯一功能是按Tab键顺序。 If I remove the DataGridRow Style, the tab order will correct itself, but the rows will not expand with the window. 如果删除DataGridRow样式,则制表符顺序将自行更正,但行不会随窗口扩展。

This problem does not seem to be isolated to the UniformGrid either as a StackPanel also produces the same tab symptoms. 这个问题似乎并没有孤立到UniformGrid上,因为StackPanel也会产生相同的选项卡症状。

Does anyone know how or what I should look for to fix this tab issue or possibly another way to make the grid expand and contract as required? 有谁知道我应该怎么寻找或寻找解决此选项卡问题的方法,或者可能是使网格根据需要扩展和收缩的另一种方法?

Example XAML: 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>

Example Code behind: 后面的示例代码:

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

The fix was super simple. 解决方法非常简单。 After reflecting out DataGridCellPanel, I noticed it had the following static constructor: 反映出DataGridCellPanel之后,我注意到它具有以下静态构造函数:

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

All that was required was to either extend UniformGrid to add that static constructor or just add an attached property KeyboardNavigation.TabNavigation="Local" to the UniformGrid in the DataGridRow style: 所需要做的就是扩展UniformGrid以添加该静态构造函数,或者只是向DataGridRow样式的UniformGrid中添加附加属性KeyboardNavigation.TabNavigation =“ Local”:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM