DependencyProperty默认值和子类化DataGrid中断属性

本文关键字:DataGrid 中断 属性 子类 默认值 DependencyProperty | 更新日期: 2023-09-27 18:20:26

在尝试对wpf的DataGrid控件进行子类化时,我遇到了一些奇怪的行为。

假设我有:

class CustomDataGrid<T> : DataGrid { ... }
class FooDataGrid : CustomDataGrid<Foo> { }

还有一些xaml:

<local:FooDataGrid ItemsSource="..." SelectionMode="Single" SelectionUnit="FullRow" />

一切都很好,我一次只能选择一行。然而,如果我试图通过这样做来更改SelectionMode/SelectionUnit的默认值:

static CustomDataGrid()
{
    DataGrid.SelectionModeProperty.OverrideMetadata( typeof( CustomDataGrid<T> ), new FrameworkPropertyMetadata( DataGridSelectionMode.Single ) );
    DataGrid.SelectionUnitProperty.OverrideMetadata( typeof( CustomDataGrid<T> ), new FrameworkPropertyMetadata( DataGridSelectionUnit.FullRow ) );
}

并将xaml更改为:

<local:FooDataGrid ItemsSource="..." />

它似乎不关心我的默认值,我可以选择多行。现在,奇怪的是,如果我再次尝试在xaml中手动设置属性(同时在静态构造函数中仍然有默认值),我仍然可以选择多行。因此,以某种方式重写元数据会破坏那些依赖属性的工作,导致wpf不关心xaml中设置的值。

有人知道这里发生了什么吗?

DependencyProperty默认值和子类化DataGrid中断属性

实际的多选行为由CanSelectMultipleItems属性控制,该属性默认为true,仅在SelectionMode属性更改时更新。重写默认值不会调用属性更改处理程序,所以CanSelectMultipleItems仍然是true。现在,如果您尝试在XAML中设置值,依赖属性系统将开始对您不利:默认值为DataGridSelectionMode.Single,并且您将属性设置为相同的值,因此不会再次调用属性更改处理程序,也不会发生任何事情。

最简单的解决方案-添加一个非静态构造函数并初始化CanSelectMultipleItems属性:

public CustomDataGrid()
{
    CanSelectMultipleItems = SelectionMode != DataGridSelectionMode.Single;
}

此外,您还可以为数据网格声明自定义样式,并在样式中设置属性值——这似乎是一种更"WPF方式"的方式。