【问题标题】:Auto cancel changes in DataForm when selection is changed更改选择时自动取消 DataForm 中的更改
【发布时间】:2010-09-07 09:12:04
【问题描述】:

我想知道你是怎么做到的。假设,我们有修改树(例如菜单结构)的 MVVM CRUD 应用程序。我们有一个带有菜单项和两个视图的视图模型:第一个带有TreeView,第二个带有DataForm。主要问题是:

  1. DataForm 无法处理 分层数据。
  2. 取决于所选的菜单项 在TreeViewDataForm 应该显示不同的集合 字段(例如菜单项 有孩子或没有孩子)。

我得到了以下结果。视图模型有 3 个字段:

  1. Items — 收藏 MenuItem 具有它们的对象 拥有Children 收藏 构建分层数据源。
  2. SelectedItem — 当前选中 MenuItemTreeView 中。
  3. EditedItemEditViewModel 基本上有两个的对象 后代:MenuItemEditViewModelLeafMenuItemEditViewModel。 该属性是自动设置的 当SelectedItem 更改时。它的 实际类型是从 SelectedItem.Children 空虚。

TreeView 绑定到 ItemsSelectedItem。在这种情况下,DataForm 不需要维护货币(而是由TreeView 设置当前项目),它也不负责创建和删除项目。这就是为什么我决定只将其CurrentItem 绑定到视图模型的EditedItemItemsSource 未绑定)。它的AutoCommit 设置为False(当它是TrueItemsSource 未绑定时,当您在TreeView 中选择不同的项目时,所有当前项目更改都会复制到新选择的项目,这不太好) . DataForm 字段是自动生成的。

显然,现在如果我们在TreeView 中选择一个项目,然后在DataForm 中进行一些更改,并尝试在TreeView 中选择不同的项目,我们会变得众所周知

当一个项目时不能改变货币 有验证错误或正在 已编辑且 AutoCommit 为 false。放 ItemsSource 到 ICollectionView 到 改为管理货币

在这种情况下,我希望 DataForm 隐式丢弃所有更改。在TreeView 所选项目更改之前调用DataForm.CancelEdit() 有一种解决方法(通常是PreviewSelectionChangedBeforeSelectionChanged 之类的事件)。但这不是 MVVM 方式,因为 TreeViewDataForm 是在完全不同的视图中定义的(读取:是不可接受的)。

CurrentItem 更改时,是否有类似 AutoCancel 的东西强制DataForm 取消更改?也许开发团队的人可以回答?或者你会如何处理这样的问题?

【问题讨论】:

  • 错误信息很明确:你需要坚持使用美元。在编辑项目并且 AutoCommit 为 false 时,您不能切换到欧元! :)

标签: silverlight mvvm currency toolkit dataform


【解决方案1】:

考虑到所有面向业务的 RIA 功能,我惊讶地发现 Silverlight 严重缺乏此功能。 AutoCommit 对我来说是不可接受的,因为我希望用户明确确认待处理的更改,而不是仅仅向数据库提交他们可能不想要的东西。

您可以使用私有成员变量可靠地跟踪DataForm的编辑模式并捕获DataForm的BeginningEdit和EditEnded事件(命名不一致!为什么一个叫xxxEdit,另一个叫Editxxx,我无法理解。应该不是EditBeginning 和 EditEnded??)。在BeginningEdit 的事件处理程序中,将标志设置为true,并在EditEnded 中将其设置为false。

在您的 SelectionChanged 事件中,您可以检查标志。如果为真,则可以在 DataForm 上调用 CancelEdit。

private bool _editing = false;

public MainPage() {
    DataForm1.BeinningEdit += 
        new EventHandler<CancelEventArgs>(DataForm1_BeginningEdit);
    DataForm1.EditEnded += 
        new EventHandler<DataFormEditEndedEventArgs>(DataForm1_EditEnded);
}

protected void DataForm1_BeginningEdit(object sender, 
    System.ComponentModel.CancelEventArgs e) {
    _editing = true;
}

protected void DataForm1_EditEnded(object sender, 
    DataFormEditEndedEventArgs e) {
    _editing = false;
}

void TreeView1_SelectedItemChanged(object sender, 
    RoutedPropertyChangedEventArgs<object> e)
{
    if (_editing) {
        object previous = DataForm1.SelectedItem;
        object current = TreeView1.SelectedItem;

        if (MessageBox.Show("Are you sure you want to cancel the changes?", 
            "Confirm", MessageBoxbutton.OKCancel) == MessageBoxResult.OK) {
            DataForm1.CancelEdit();
        }
        else {
            TreeView1.SelectedItem = previous;
        }
    }
}

【讨论】:

  • 谢谢!但我已经更改了 DataForm 源以满足我的需要。我非常喜欢你关于询问用户确认的建议(在我目前的情况下,如果用户没有明确保存,所有更改都会被取消)。
【解决方案2】:

您是否尝试将 AutoCommit 设置为 True ?

【讨论】:

  • 是的,这不是一个解决方案。我提到它:“当它为 True 并且 ItemsSource 未绑定时,当您在 TreeView 中选择不同的项目时,所有当前项目更改都会复制到新选择的项目,这不太好”
猜你喜欢
  • 2011-10-14
  • 2014-12-05
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 2021-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多