How to implement in WPF a confirmation for opening a new file => unsaved changes lost?
I am implementing an application with modelviewviewmodel, i have one view, where you can change all the properties of an object, this object is a property of a viewmodel from the view. But it also have te menu bar like windows, with file => open, new file, save, save as.. If i click on new file, the application have to make a total new object. It works fine, so the object is resetted. Every field and things becomes empty again. But now i want to implement a confirmation window, because if the user clicks accidently on new file, he loses everything. and in that confirmation window, i have 2 buttons, yes and no: yes, the applicati开发者_开发百科on resets all the values, but if he clicks on no, the window just closes and the user can work further with the current object. My problem is with the yes button. It is a window, but the method, to create a new object, is in my viewmodel. So in my viewmodel is:
this.Examination = new Examination();
Without confirmation, i just go from my view to this method in the viewmodel, but now how can i go from the confirmation window (after clicking on yes) to my viewmodel?
SOmeone who can help me out please?
Create a command in your view model that creates the new object and bind the yes button to that command.
<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;}
}
There are a couple of ways to approach the problem.
The simplest is to just use MessageBox.Show
in your view model. This is simple to code and easy to understand. It also breaks your ability to unit test the view model, since now its behavior is to block and wait on user input.
The next step up the complexity chain is to define an interface for view models to use when they need to ask a yes-or-no question. For instance:
public interface IConfirmationDialogService
{
bool Show(string question);
}
Your view model then implements a property:
public IConfirmationDialogService ConfirmationDialogService { get; set; }
and you implement a service class for use by the view model when it's in your application:
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;
}
}
Now anywhere in your view model, you can get confirmation from the user:
if (!ConfirmationDialogService.Show("Do you want to do this?"))
{
return;
}
How do you unit test this? With mocking. In your unit tests, you implement a class for mocking user input:
public class MockConfirmationDialogService : IConfirmationDialogService
{
public MockConfirmationDialogService(bool result)
{
_Result = result;
}
private bool _Result;
public bool Show(string question)
{
return _Result;
}
}
so that you can test your methods that wait for user input, e.g.:
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);
The next step up in complexity is when you realize that this is but one of the many issues you're going to have implementing dialogs in view models, and that instead of having an IConfirmationDialogService
for yes-or-no questions, you're going to need a more robust dialog service that can handle dialogs of all kinds. By then you'll be well on your way to implementing your own view model framework, and you should start taking a look at existing view model frameworks to see how they do it.
精彩评论