如何在WPF中实现打开新文件的确认=>未保存的更改丢失了?

发布于 2024-12-01 08:19:03 字数 483 浏览 6 评论 0原文

我正在使用 modelviewviewmodel 实现一个应用程序,我有一个视图,您可以在其中更改对象的所有属性,该对象是视图中视图模型的属性。但它也有像 Windows 一样的菜单栏,其中有 file =>打开,新文件,保存,另存为.. 如果我单击新文件,应用程序必须创建一个全新的对象。它工作正常,因此该对象已重置。所有的领域和事物都再次变得空虚。但现在我想实现一个确认窗口,因为如果用户意外单击新文件,他就会丢失所有内容。在该确认窗口中,我有 2 个按钮,是和否:是,应用程序会重置所有值,但如果他单击“否”,窗口就会关闭,用户可以进一步处理当前对象。我的问题是“是”按钮。它是一个窗口,但创建新对象的方法位于我的视图模型中。所以在我的视图模型中是:

 this.Examination = new Examination();

没有确认,我只是从我的视图转到视图模型中的此方法,但现在我如何从确认窗口(单击“是”后)转到我的视图模型?

有人可以帮我吗?

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 application 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

笑看君怀她人 2024-12-08 08:19:03

在视图模型中创建一个命令来创建新对象并将“是”按钮绑定到该命令。

<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;}
     }

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;}
     }
揪着可爱 2024-12-08 08:19:03

有几种方法可以解决这个问题。

最简单的方法是在视图模型中使用 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);

复杂性的下一步是当您意识到这只是您遇到的众多问题之一时我们将在视图模型中实现对话框,并且您将需要一个更强大的对话框服务来处理各种类型的对话框,而不是使用 IConfirmationDialogService 来回答是或否问题。到那时,您将很好地实现自己的视图模型框架,并且您应该开始查看现有的视图模型框架以了解它们是如何实现的。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文