2

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

  1. DataForm无法处理分层数据。
  2. 根据在 中选择的菜单项TreeView应该DataForm 显示不同的字段集(例如对于有子项或没有子项的菜单项)。

我结束了以下内容。视图模型有 3 个字段:

  1. ItemsMenuItem对象的集合,它们有自己的Children集合,用于构建分层数据源。
  2. SelectedItem— 当前 MenuItemTreeView.
  3. EditedItemEditViewModel 基本上有两个后代的对象:MenuItemEditViewModelLeafMenuItemEditViewModel. 此属性在SelectedItem更改时自动设置。SelectedItem.Children它的实际类型是从空虚中推断出来的 。

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

显然,现在如果我们在 中选择一个项目,TreeView然后DataFormTreeView

当项目存在验证错误或正在编辑且 AutoCommit 为 false 时,无法更改货币。将 ItemsSource 设置为 ICollectionView 以改为管理货币

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

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

4

2 回答 2

4

考虑到所有面向业务的 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;
        }
    }
}
于 2010-11-29T19:21:36.257 回答
0

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

于 2010-10-22T15:01:25.230 回答