单击取消按钮时如何在WPF子窗口中回滚更改的数据

时间:2016-07-18 09:06:03

标签: c# wpf mvvm binding

好的,我们假设Parent Window绑定到DataContext现在假设我们触发Child Window并将其数据上下文设置为父窗口的数据上下文。现在,子窗口中的项目以TwoWay模式绑定到数据上下文。当用户在此子窗口中更改某些内容时,将更新源视图模型中的数据。但是如果用户使用DialogResult == false关闭窗口会怎么样?如何将数据回滚到原始数据?

目前我在OneWay模式下绑定数据并仅在DialogResult == true时应用更改。但我想必须有更优雅的方式来做到这一点。

3 个答案:

答案 0 :(得分:1)

将绑定上的UpdateSourceTrigger更改为显式,并仅在单击“确定”按钮时调用UpdateSource方法。

UpdateSourceTrigger

答案 1 :(得分:1)

IEditableObject

与WPF使用System.ComponentModel.INotifyPropertyChanged的方式相同,您也可以使用界面System.ComponentModel.IEditableObject。此接口具有以下有用的方法:

在显示窗口之前,请在datacontext上调用BeginEdit()。现在,任何更改都会通过通常的INotifyPropertyChanged反映,以便父级照常接收更新。

如果用户取消,则调用CancelEdit(),此时您的viewmodel应回滚更改。免费的牛排刀是通过INotifyPropertyChanged告知您的父窗口回滚,从而恢复"父窗口也是。

否则请致电EndEdit(),因为更改已经完成,因此无需提及。

显然,您需要以某种方式记住先前的值,以便您可以恢复任何更改。

IRevertibleChangeTracking

我刚刚阅读了提供方法System.ComponentModel.IRevertibleChangeTrackingAcceptChanges()的{​​{1}}。虽然可以说这是用于接受回滚更改的界面,但是在WPF场景中是否应该广播过程中所做的更改并不完全清楚。也许有人可以帮助我。

Tell me more...

答案 2 :(得分:1)

例如,您可以将确认的值绑定为主视图中的单向,readonly和对话框文本框中的未提交值。

ViewModel
    class MyVM : MVVM.ViewModel.ViewModelBase
    {
        private string name1;
        public string Name1
        {
            get { return name1; }
            set {
                name1 = value;
                OnPropertyChanged(() => Name1);
            }
        }
        string name1Conf;
        public string Name1Conf
        {
            get { return name1Conf; }
        }
        private string name2;
        public string Name2
        {
            get { return name2; }
            set
            {
                name2 = value;
                OnPropertyChanged(() => Name2);
            }
        }
        string name2Conf;
        public string Name2Conf
        {
            get { return name2Conf; }
        }

        private bool commitMe;

        public bool CommitMe
        {
            get { return commitMe; }
            set {
                commitMe = value;
                OnPropertyChanged(() => CommitMe);
                if (commitMe)
                {
                    DoCommit();
                } 
            }
        }

        private void DoCommit()
        {
            name1Conf = name1;
            name2Conf = name2;
            OnPropertyChanged(() => Name1Conf);
            OnPropertyChanged(() => Name2Conf);
        }
    }

代码隐藏

private void button_Click(object sender, RoutedEventArgs e)
{
    var win2 = new WPFDialog();
    win2.DataContext = myVM;
    var res = win2.ShowDialog();
    myVM.CommitMe = res == true;
}