我正在处理一个 WPF 项目,该项目需要一个需要在窗口中扩展和收缩的 2D 网格。 为了做到这一点,我用UniformGrids替换了DataGrid中的ItemsPanel。 当我这样做时,控件会正确扩展和收缩。
遗憾的是,由于某种原因,这会破坏 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));
}
}
}
修复非常简单。 在反射出DataGridCellPanel之后,我注意到它有以下静态构造函数:
static DataGridCellsPanel()
{
KeyboardNavigation.TabNavigationProperty.OverrideMetadata(typeof(DataGridCellsPanel), new FrameworkPropertyMetadata((object)KeyboardNavigationMode.Local));
}
所需要的只是扩展 UniformGrid 以添加该静态构造函数,或者只是在 DataGridRow 样式中将附加属性 KeyboardNavigation.TabNavigation="Local" 添加到 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>