好的,我们假设Parent Window
绑定到DataContext
现在假设我们触发Child Window
并将其数据上下文设置为父窗口的数据上下文。现在,子窗口中的项目以TwoWay
模式绑定到数据上下文。当用户在此子窗口中更改某些内容时,将更新源视图模型中的数据。但是如果用户使用DialogResult == false
关闭窗口会怎么样?如何将数据回滚到原始数据?
目前我在OneWay
模式下绑定数据并仅在DialogResult == true
时应用更改。但我想必须有更优雅的方式来做到这一点。
答案 0 :(得分:1)
将绑定上的UpdateSourceTrigger
更改为显式,并仅在单击“确定”按钮时调用UpdateSource
方法。
答案 1 :(得分:1)
与WPF使用System.ComponentModel.INotifyPropertyChanged
的方式相同,您也可以使用界面System.ComponentModel.IEditableObject
。此接口具有以下有用的方法:
BeginEdit()
EndEdit()
- 我们的使用并非真正需要CancelEdit()
在显示窗口之前,请在datacontext上调用BeginEdit()
。现在,任何更改都会通过通常的INotifyPropertyChanged
反映,以便父级照常接收更新。
如果用户取消,则调用CancelEdit()
,此时您的viewmodel应回滚更改。免费的牛排刀是通过INotifyPropertyChanged
告知您的父窗口回滚,从而恢复"父窗口也是。
否则请致电EndEdit()
,因为更改已经完成,因此无需提及。
显然,您需要以某种方式记住先前的值,以便您可以恢复任何更改。
我刚刚阅读了提供方法System.ComponentModel.IRevertibleChangeTracking
和AcceptChanges()
的{{1}}。虽然可以说这是用于接受和回滚更改的界面,但是在WPF场景中是否应该广播过程中所做的更改并不完全清楚。也许有人可以帮助我。
答案 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;
}