如何在WPF中实现打开新文件的确认=>未保存的更改丢失了?
我正在使用modelviewviewmodel实现一个应用程序,我有一个视图,您可以在其中更改对象的所有属性,此对象是视图中视图模型的属性。但它也有像菜单栏的窗口,文件=>打开,新文件,保存,另存为..如果我点击新文件,应用程序必须作出一个全新的对象。它工作正常,所以对象被重置。每个领域和事物都会变得空虚。但是现在我想实现一个确认窗口,因为如果用户意外地点击新文件,他会失去一切。并在该确认窗口中,我有2个按钮,是和否:是的,应用程序重置所有值,但是如果他单击否,窗口会关闭,用户可以继续使用当前对象。我的问题是与是按钮。这是一个窗口,但创建一个新对象的方法在我的视图模型中。所以在我的视图模型为:如何在WPF中实现打开新文件的确认=>未保存的更改丢失了?
this.Examination = new Examination();
没有确认,我只是从我的观点去这个方法在视图模型,但是现在我如何从确认窗口去我的视图模型(点击是之后)?
SOmeone谁可以帮助我吗?
在您的视图模型中创建一个用于创建新对象并将yes按钮绑定到该命令的命令。
<Button Command="{Binding CreateNewExaminationCommand, Source={x:Static viewmodel:ExaminationViewModel.Instance}}"></Button>
// VIEWMODEL
RelayCommand createNewExaminationCommand;
public ICommand CreateNewExaminationCommand
{
get
{
if (createNewExaminationCommand== null)
{
createNewExaminationCommand= new RelayCommand(param => this.CreateNew(),
param => this.CanCreateNew);
}
return createNewExaminationCommand;
}
}
private ExaminationViewModel() {}
private static readonly ExaminationViewModel instance = new ExaminationViewModel();
public static ExaminationViewModel Instance
{
get {return instance;}
}
有几种方法可以解决这个问题。
最简单的就是在您的视图模型中使用MessageBox.Show
。这很简单,易于理解。它也打破了单元测试视图模型的能力,因为现在它的行为是阻止并等待用户输入。
复杂性链的下一步是为视图模型定义一个接口,以便在他们需要询问是或否的问题时使用。例如:
public interface IConfirmationDialogService
{
bool Show(string question);
}
您的视图模型,然后实现它的属性:
public IConfirmationDialogService ConfirmationDialogService { get; set; }
,你实现服务类由视图模型使用的时候它在你的应用程序:
public class ViewConfirmationDialogService : IConfirmationDialogService
{
public string Caption { get; set; }
public bool Show(string question)
{
return MessageBox.Show(
string question,
Caption,
MessageBoxButtons.YesNo,
MessageBoxImage.Question) == MessageBoxResult.Yes;
}
}
现在在您的视图模型中的任何地方,您都可以从用户那里得到确认:
if (!ConfirmationDialogService.Show("Do you want to do this?"))
{
return;
}
你是如何测试这个的?嘲笑。在单元测试中,你实现一个类嘲讽用户输入:
public class MockConfirmationDialogService : IConfirmationDialogService
{
public MockConfirmationDialogService(bool result)
{
_Result = result;
}
private bool _Result;
public bool Show(string question)
{
return _Result;
}
}
,让你可以测试你的方法是等待用户输入,如:
MyViewModel vm = new MyViewModel()
ConfirmationDialogService = new MockConfirmationDialogService(false);
vm.ExecuteCommand();
Assert.IsFalse(vm.CommandChangedSomething);
vm.ConfirmationDialogService = new MockConfirmationDialogService(true);
vm.ExecuteCommand();
Assert.IsTrue(vm.CommandChangedSomething);
下一步起来的复杂性当你意识到这只是你在视图模型中实现对话的许多问题中的一个,并且对于yes-no问题而不是IConfirmationDialogService
,你将需要更强大的对话服务可以处理各种对话。届时,您将很好地实现自己的视图模型框架,并且应该开始查看现有的视图模型框架,以了解它们是如何实现的。
这不起作用,我认为是因为'popup'没有绑定viewmodel,系统没有调用这个方法,或者我错了吗? – Ruben
如果你的弹出窗口没有绑定到你的视图模型,那么你可以让你的视图模型成为一个singleton,并将它添加到你的按钮的绑定源(参见上面的编辑)。或者你在使用MessageBox?如果您是从代码隐藏中调用该命令。 – evanb
感谢它现在正常工作! – Ruben