需要为 Telerik UWP 扩展 DataGridNumericalColumn

Need to extend DataGridNumericalColumn for Telerik UWP

我需要创建自定义版本的 UWP DataGridNumericalColumn,允许自定义 RadNumericBox 属性(ValueFormatButtonsVisibilitySmallChange, LargeChange, Value) 以及在编辑时将值编辑为没有小数位的美分 (199),但在不编辑时显示为带小数美分 (1.99) 的普通美元。我已经尝试了两种不同的方法来扩展现有的控件,但我似乎都无法完全发挥作用。

1) 尝试从 DataGridNumericalColumn 派生 - 由于无法访问内部成员而无法实现,即使有来自 GitHub 的完整源代码可用。

2) 尝试从 DataGridTemplateColumn 派生 - 对于初始显示有些可行,但与内联编辑模式与显示模式和单元格上显示的验证消息相关的所有内容似乎都无法实现(不可覆盖)并且我似乎无法使用 CellContentTemplateSelector 在内联编辑模式 RadNumericBox 显示和正常 TextBlock 显示之间进行选择,因为我似乎无法检测到何时将编辑模式应用于单元格。

开始看来我能实现我需要的唯一方法是分叉 GitHub 代码库,这样我就可以从 DataGridNumericalColumn 派生并访问内部代码。

我可以采用什么方法来实现我想要的自定义?

(在撰写本文时,我正在使用 Telerik UI 通用 Windows 平台,版本 2017.1.301.45。)

我最终找到了解决方法,让我克服了使用从 DataGridTemplateColumn 派生的方法扩展此功能的主要困难。以下是我所做的更新和定制 - 它们主要是在概念层面上描述的,但其他人自己复制这种定制应该足够了。

更新1: 我一直在做的更新: 继续使用从 DataGridTemplateColumn 派生的方法,我发现我可以通过在网格中创建用于编辑操作的自定义命令(CustomBeginEditCommandCustomCancelEditCommand,和 CustomCommitEditCommand 非常类似于 http://docs.telerik.com/devtools/universal-windows-platform/controls/raddatagrid/features/commands/editing-commands/datagrid-editingcommands-begineditcommand 中的那些)以及一个接口 IItemAwareOfEditMode,应用于网格数据的 ViewModel 项,它有一个布尔值 属性 IsInEditMode 我在自定义命令中适当地设置为 truefalse,然后在自定义 DataTemplateSelector 中使用它来决定何时应用我的编辑标记与我的显示标记。这使用 (DataTemplate)XamlReader.LoadWithInitialTemplateValidation(editControlMarkup) 将动态创建的标记字符串转换为 DataTemplates。对于我的实现,我在 PropertyChangedCallback 中为自定义列的 PropertyNameProperty 依赖项 属性.

创建标记

但是,我在验证和显示验证消息以及在用户取消编辑时恢复值方面仍然存在问题。我实现了网格行项的 ViewModel,以便它们派生自 ValidateViewModelBase,因此根据 CreateEditorContainerhttp://docs.telerik.com/devtools/universal-windows-platform/controls/raddatagrid/features/validation . If I use the DataGridNumericalColumn (not customized) with the same data, the validation messages do appear pointing to the cell when the data is invalid, but with my custom column, HasErrors is true on the items, but the validation messages don't appear. Looking at the validation code in https://github.com/telerik/UI-For-UWP/blob/master/Controls/Grid/Grid.UWP/View/Columns/TypedColumns/DataGridTypedColumn.cs 处的验证文档,它们 add/remove 会适当地出错功能,似乎有一个 EditRowHostPanelValidationControl 与编辑器内容一起涉及,但我无法访问完全按照那里的方式实现容器所需的部分。

我怎样才能使验证消息像在 DataGridNumericalColumn 中那样显示?

此外,我该怎么做才能取消编辑(在编辑模式下单击该行的蓝色 X)实际上将自定义列的值恢复到进入编辑模式之前的值?

更新2: 我一直在做的另一个更新: 继续使用从 DataGridTemplateColumn 派生的方法,我成功地通过在编辑模式模板标记中包含 ValidationControl 来成功显示编辑模式的验证消息,它引用了 RadNumericBox从模板(按名称)使用 ControlPeer 属性,并为其 DataItem 属性 赋值 "{Binding}",并适当填充其 PropertyName.

这已经接近我的需要了,但我的CustomCancelEditCommand似乎使用了

Owner.CommandService.ExecuteDefaultCommand(CommandId.CancelEdit, context);

,没有适当地将单元格的显示更新为其先前的值。当取消内联行编辑时,它不会正确地调用 CustomCommitEditCommand;但是,它显示为修改后的值(不会恢复为编辑前的值)。即使您再次编辑,该值在网格中显示时仍为修改后的值。

我看到在 Execute 方法的 https://github.com/telerik/UI-For-UWP/blob/master/Controls/Grid/Grid.UWP/View/Services/Commands/Editing/CancelEditCommand.cs 中,它执行了它的基本实现,然后是

Owner.editService.CancelEdit(context.TriggerAction)

,我不明白(RadDataGrid 不包含 editService 的定义,我无法从 CancelEditCommand class 中得出,因为它是内部)。

如何取消编辑(在编辑模式下单击行的蓝色 X)实际上将自定义列的值恢复到进入编辑模式之前的值?

更新3: 我终于找到了一个广泛的解决方法,它确实在取消时恢复了我的自定义列的值。

我对涉及的取消功能的解决方法: 1) 创建了一个 CustomRadDataGrid,派生自 RadDataGrid.

2) 给了我的CustomRadDataGridclass一个CustomEditingService属性,这是一个CustomEditingService,是从[=51复制和修改的代码=](主要注释掉不需要的部分,但也更改 InitializeEditOperation 的实现并更改 CancelEdit 以具有操作的 OriginalValues 字典的 out 参数),并且派生自 CustomServiceBase<RadDataGrid>,它是从 ServiceBase 复制和修改的代码(将 IsOperational 更改为 return Owner.DataContext != null),它派生自 CustomAttachableObject<T> where T : RadControl,它是从 AttachableObject.

3) 向我的自定义列添加了 GetActualValueForInstance 函数和 SetActualValueForInstance 方法,它使用反射 get/set 此列的数据行实例的值(基于使用我的 PropertyName 依赖项 属性 的值),并使我的 CustomEditingServiceInitializeEditOperation 只保存我的自定义列的原始值,并使我的 CancelEdit 49=] return 输出变量中原始值的字典。

4) 在调用 Owner.CommandService.ExecuteDefaultCommand(CommandId.BeginEdit, context) 之后在网格的 CustomEditingService 上进行了 CustomBeginEditCommand 调用 BeginEdit - 这允许存储我的自定义列原始值。

5) 在调用 Owner.CommandService.ExecuteDefaultCommand(CommandId.CommitEdit, context) 之后在网格的 CustomEditingService 上进行了 CustomCommitEditCommand 调用 CommitEdit - 这允许我的自定义编辑服务正确跟踪其编辑状态。

6) 在网格的 CustomEditingService 上进行 CustomCancelEditCommand 调用 CancelEdit 并且对于每个原始值字典项,使用 Key(列,作为我的自定义列) SetActualValueForInstance 在调用 Owner.CommandService.ExecuteDefaultCommand(CommandId.CancelEdit, context) 之前传入 context.CellInfo.ItemValue(先前存储的原始值)- 在标准取消操作发生之前恢复我的自定义列原始值。

完成!哇...看来这个库需要进行大量更改才能实现更好的扩展能力。根据对我的支持票的回复,这已在 Telerik 记录为功能请求。

我认为其他人也希望能够扩展 Telerik 的各种 DataGridColumn 控件,所以我在这里分享了我的努力和(最终)成功的定制。