2

在尝试对 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 中设置的值。

有谁知道这里发生了什么?

4

1 回答 1

1

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

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

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

您还可以为您的数据网格声明自定义样式并在样式中设置属性值 - 执行此类操作似乎更像是一种“WPF 方式”。

于 2013-06-28T10:39:15.533 回答