【问题标题】:Reverting an object is a user clicks "Cancel" in WPF还原对象是用户在 WPF 中单击“取消”
【发布时间】:2011-12-25 16:20:12
【问题描述】:

我有一个用作 WPF 应用程序中的对话框的窗口。该对话框有一个“确定”和一个“取消”按钮。我正在将 Window 的 DataContext 设置为我的应用程序中的对象实例。用户可以更改窗口内对象的属性值。如果用户单击“取消”,我想将属性值恢复为原始值。在 WPF 中是否有一种简单的方法可以做到这一点?

例如,我知道 RIA 数据服务有 RejectChanges。 WPF 在客户端有类似的东西吗?

谢谢!

【问题讨论】:

    标签: wpf


    【解决方案1】:

    在设置为 DataContext 的对象中(理想情况下它应该是 MVVM 方法中的 ViewModel)公开两个命令

    public ICommand CancelCommand { get; set; }
    public ICommand OkCommand { get; set; }
    

    然后为按钮分配这些命令,如下所示

    <Button Command="{Binding CancelCommand}" ... />
    

    您必须保留两个对象副本,一个副本应该由Deep Copy 创建,或者如果一个对象有一些可编辑字段,您可以将它们保留为类字段。基本上在初始化阶段备份可编辑对象属性,然后绑定到DataContext 对象的可编辑版本。在取消命令处理程序中 - 从备份副本恢复...

    【讨论】:

    • 而.NET 正是为此目的定义了IEditableObject 接口。当对话框打开时,您将调用BeginEdit。当它关闭时,您可以调用EndEditCancelEdit,具体取决于单击的按钮。
    • 是的,如果比 applyedit 或 endedit 正确,并且如果 CacelEdit 拒绝更改,您可以保持对象 beginedit 的旧状态
    • @Kent Boogaart:嗨,肯特!感谢您指出这一点。使用这个内置界面有什么好处吗?还是只是遵循标准方法?此外,从 MVVM 的角度来看,它如何用于将按钮单击与恢复状态逻辑联系起来?
    • 优点(除了标准之外)是支持IEditableObject(如DataGrid)的控件会自动代表您调用它。您可以为同样查找IEditableObject 的对话框创建自己的基类,并根据需要调用其方法。否则,您可以让您的虚拟机执行此操作 - 您打开对话框的命令将调用 BeginEdit,它会根据对话框结果调用其他两种方法之一。您可以通过窗口管理服务来完成所有这些操作,以使您的 VM 不受任何视图问题的影响。
    • @Kent Boogaart:好东西!谢谢!我会研究一下,当然我想了解它是如何工作的,尤其是控件如何/何时能够代表我自动调用它的成员(我也新听说过 Windows 管理服务,所以有很多东西要复习)。谢谢!
    【解决方案2】:

    当对象很简单(只有字符串、int等基本类型的几个属性)时,DeepCopy或IEditableObject是一个很好的选择。

    当对象是更复杂层次结构中的一个节点时,这可能证明太难了,回到服务器/模型并重新加载原始数据要容易得多。

    【讨论】:

    • 我相信 Deep Copy(无论是序列化还是反射)都可以处理任何复杂的节点,我错了吗?我相信服务器调用无论如何都非常昂贵,因为您已经在内存中有一个对象,所以随心所欲地使用它,它会(我相信)更便宜,而不是网络请求/响应
    • IEditableObject 没有规定您如何实施编辑/提交/回滚行为。可能是您在幕后进行序列化/反序列化,或者您只是在复制字段,或者您要返回服务器/数据库以刷新数据对象。复杂的层次结构并不妨碍您实施IEditableObject
    • 我并不是说这是不可能的,我只是建议根据对象树的复杂性,它会变得相当困难。是的,DeepCopy 是一种实现 IEditableObject 的方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-13
    • 2013-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-06
    相关资源
    最近更新 更多