我最终找到了解决方法,让我克服了使用从DataGridTemplateColumn 派生方法扩展此功能的主要困难。以下是我所做的更新和自定义 - 它们主要是在概念级别上描述的,但其他人自己复制这种自定义应该就足够了。
更新1:
我一直在做的更新:
继续使用从DataGridTemplateColumn 派生的方法,我发现我可以通过在网格中创建用于编辑操作的自定义命令(CustomBeginEditCommand、CustomCancelEditCommand 和@987654329 @ 非常类似于 http://docs.telerik.com/devtools/universal-windows-platform/controls/raddatagrid/features/commands/editing-commands/datagrid-editingcommands-begineditcommand 中的那些)以及一个接口 IItemAwareOfEditMode,应用于 Grid 数据的 ViewModel 项,它有一个布尔属性 IsInEditMode 我适当地设置为 true 或 false在自定义命令中,然后在自定义DataTemplateSelector 中使用它来决定何时应用我的编辑标记和我的显示标记。这使用(DataTemplate)XamlReader.LoadWithInitialTemplateValidation(editControlMarkup) 将动态创建的标记字符串转换为DataTemplates。对于我的实现,我在 PropertyChangedCallback 中为我的自定义列的 PropertyNameProperty 依赖属性创建标记。
但是,我仍然在验证和显示验证消息以及在用户取消编辑时恢复值方面遇到问题。我已经实现了网格行项目的 ViewModel,它们从ValidateViewModelBase 派生,因此它们根据http://docs.telerik.com/devtools/universal-windows-platform/controls/raddatagrid/features/validation 的验证文档适当地添加/删除错误。如果我对相同数据使用DataGridNumericalColumn(未自定义),当数据无效时,验证消息确实会出现指向单元格,但对于我的自定义列,HasErrors 在项目上为真,但验证消息不要出现。查看CreateEditorContainer 函数中CreateEditorContainer 中的验证代码,似乎与编辑器内容一起涉及EditRowHostPanel 和ValidationControl,但我无法访问完全实现容器所需的部分和那里一样。
我该怎么做才能让验证消息像在DataGridNumericalColumn 中一样显示?
另外,我可以做些什么来取消编辑(在编辑模式下单击行的蓝色 X)实际上将我的自定义列的值恢复为进入编辑模式之前的值?
更新 2:
我一直在做的另一个更新:
继续使用从DataGridTemplateColumn 派生的方法,我通过在编辑模式模板标记中包含ValidationControl 成功地显示了编辑模式的验证消息,该标记引用模板中的RadNumericBox(按名称) 使用ControlPeer 属性,并为其DataItem 属性赋予值"{Binding}",并适当填充其PropertyName。
这已经接近我需要的了,但似乎我的CustomCancelEditCommand 使用了
Owner.CommandService.ExecuteDefaultCommand(CommandId.CancelEdit, context);
,没有适当地将单元格的显示更新为其先前的值。当内联行编辑被取消时,它不会正确调用CustomCommitEditCommand;但是,它显示为修改后的值(未恢复为编辑前的值)。即使您再次编辑,该值在网格中显示时仍保持为修改后的值。
我在https://github.com/telerik/UI-For-UWP/blob/master/Controls/Grid/Grid.UWP/View/Services/Commands/Editing/CancelEditCommand.cs 的Execute 方法中看到,它执行了它的基本实现,然后是
Owner.editService.CancelEdit(context.TriggerAction)
,我不明白(RadDataGrid 不包含 editService 的定义,我不能从 CancelEditCommand 类派生,因为它是内部的)。
我可以做些什么来取消编辑(在编辑模式下单击行的蓝色 X)实际上将我的自定义列的值恢复为进入编辑模式之前的值?
更新3:
我终于管理了一个广泛的解决方法,它确实在取消时恢复了我的自定义列的值。
我对所涉及的取消功能的解决方法:
1) 创建了一个CustomRadDataGrid,它派生自RadDataGrid。
2) 给我的CustomRadDataGrid 类一个CustomEditingService 属性,这是一个CustomEditingService,它是从EditingService 复制和修改的代码(主要是注释掉不需要的部分,但也会更改InitializeEditOperation 的实现并将 CancelEdit 更改为具有操作的 OriginalValues 字典的 out 参数),它派生自 CustomServiceBase<RadDataGrid>,它是从 ServiceBase 复制和修改的代码(将 IsOperational 更改为返回 Owner.DataContext != null),其中派生自CustomAttachableObject<T> where T : RadControl,是从AttachableObject复制代码。
3) 在我的自定义列中添加了GetActualValueForInstance 函数和SetActualValueForInstance 方法,它使用反射来获取/设置该列的数据行实例的值(基于使用我的PropertyName 依赖属性的值),并制作我的CustomEditingService 的InitializeEditOperation 只是保存我的自定义列的原始值,并使我的CustomEditingService 的CancelEdit 在输出变量中返回该原始值字典。
4) 在调用Owner.CommandService.ExecuteDefaultCommand(CommandId.BeginEdit, context) 之后,在网格的CustomEditingService 上调用CustomBeginEditCommand BeginEdit - 这样可以存储我的自定义列原始值。
5) 在调用Owner.CommandService.ExecuteDefaultCommand(CommandId.CommitEdit, context) 之后,在网格的CustomEditingService 上调用CustomCommitEditCommand CommitEdit - 这允许我的自定义编辑服务正确跟踪其编辑状态。
6) 在网格的CustomEditingService 上创建我的CustomCancelEditCommand 调用CancelEdit AND 对于每个原始值字典项,使用Key(列,作为我的自定义列)SetActualValueForInstance 传入context.CellInfo.Item 和Value(之前存储的原始值),在调用 Owner.CommandService.ExecuteDefaultCommand(CommandId.CancelEdit, context) 之前 - 在标准取消操作发生之前恢复我的自定义列原始值。
完成!唷...看来这个库需要进行大量更改以实现更好的扩展能力。根据我在此主题上与他们的支持票的回复,这已被记录为 Telerik 的功能请求。
我认为其他人也希望能够扩展 Telerik 的各种 DataGridColumn 控件,因此我在这里分享了我的奋斗和(最终)成功的自定义。