如何在WPF DataGrid中获取SelectedCells的“锚点”单元格?

时间:2018-08-14 18:08:43

标签: c# wpf datagrid

我正在编码WPF程序,该程序通过绑定到DataGrid的ItemsSource属性来显示DataTable。

然后,我设置以下DataGrid的属性以选择多个单元格。

SelectionMode="Extended"
SelectionUnit="CellOrRowHeader"

此外,我想在代码后面添加一个处理程序,以将值设置为DataGrid的SelectedCells属性并更改“锚点”单元格(我的意思是,在按住Shift键的同时选择其他单元格时,锚点单元格是始终包含在SelectedCells中的单元格)。

但是我不知道如何以编程方式访问Anchor单元的信息。

请给我建议。 感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我意识到这个问题现在有点老了,但希望这些信息对某人有所帮助。

据我所知,没有可用于 DataGrid 的公共 API 允许读取选择锚点,也没有允许在不清除现有选择的情况下设置选择锚点。

为了解决这个问题,我查看了 WPF 的源代码(在撰写本文时,this 用于 .NET Framework 4.8,this 用于 .NET(以前称为 .NET Core))和确定选择锚点似乎仅由名为 Nullable<DataGridCellInfo>_selectionAnchor 类型字段处理。

对于以编程方式调整 DataGrid 选择的任何人,您只需在操作后设置 _selectionAnchor,以便后续 SHIFT 选择操作正常运行。

如果您希望清除刚刚以编程方式取消选择所有单元格的选择锚点,只需将选择锚点设置为 null

您可以找到有关反射 here 的更多信息。

TLDR:使用反射访问私有 _selectionAnchor 字段

例如:
// These lines of code are not intended to do anything more than demonstrate usage of reflection to get and set this private field.
// In reality you'd be passing SetValue() something other than the value the field was already set to.
var fieldInfo = typeof(DataGrid).GetField("_selectionAnchor", BindingFlags.Instance | BindingFlags.NonPublic);

var anchorCellInfo = fieldInfo.GetValue(dataGridInstance) as DataGridCellInfo?;

fieldInfo.SetValue(dataGridInstance, anchorCellInfo);

注意: 使用反射访问私有/内部功能总是会带来风险,即您正在访问的事物的维护者可能会在未来版本的任何时候更新这些私有/内部部分,而无需事先警告。也就是说,据我所知,这个特殊的功能在 WPF 中多年来几乎没有变化,所以你应该没问题。

为了安全起见,您可能会添加单元测试以验证您正在访问的私有/内部功能是否继续存在并以您需要的方式运行,以便您的应用程序不会巧妙地破坏在更新您使用反射访问私有/内部功能的包之后的运行时。

我要强调的是,项目的单元测试很少会测试其依赖项中的功能,但在我看来,这似乎是一个独特的案例。