视图模型的单独项目可以“强制"执行模型. MVVM:如何打开对话框? [英] Separate project for view models to "enforce" MVVM: How do I open dialogs?

查看:67
本文介绍了视图模型的单独项目可以“强制"执行模型. MVVM:如何打开对话框?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在坚持MVVM模式的同时打开对话框似乎是常规问题之一(在这里和其他地方).我知道有像MVVM light这样的框架可以解决这个问题,但是我目前正在从事一个非常小的个人项目,在该项目中,我尝试自己做大部分工作,以达到学习目的.

Opening dialogs while adhering to the MVVM pattern seems to be one of the regular questions (here and elsewhere). I know there are frameworks like MVVM light who have answers to that problem, but I'm currently working on a very small personal project where I try to do most of the stuff myself for learning purposes.

为了迫使"我自己注意参考,我决定从UI项目中提取视图模型,并将其放入单独的程序集中. UI项目引用UI.ViewModels,但并非相反.这导致我在打开(模式)对话框窗口时遇到问题.

To "force" myself to pay attention to the references, I decided to extract the view models from the UI project and put them into a separate assembly. The UI project references UI.ViewModels, but not the other way round. This led to me having problems with opening (modal) dialog windows.

许多人似乎正在使用DialogService来执行以下操作:

Many people seem to be using a DialogService which does something along the lines of:

internal class DialogService : IDialogService
{
  public bool? OpenDialog(ViewModelBase vm)
  {
    Window window = new Window();
    window.Content = vm;
    return window.ShowDialog();
  }
}

可以使用DataTemplate从视图模型类型推断相应的窗口内容.

The corresponding window content can be inferred from the view model type by using a DataTemplate.

但是在我的场景中,由于DialogService需要在UI项目中,所以这是行不通的,但是我必须从视图模型中调用它.我当然可以滥用DI/IoC将IDialogService实现注入到我的视图模型中,但这不是我想要做的.

In my scenario though, this doesn't work since the DialogService needs to be in the UI project, but I have to call it from a view model. I could of course abuse DI/IoC to inject an IDialogService implementation into my view models, but that's not what I want to do.

是否有严格的方法可以使其正常工作?

作为替代方案,我在我的ViewModelBase中添加了以下代码:

As an alternative, I have added the following code to my ViewModelBase:

public abstract class ViewModelBase : INotifyPropertyChanged
{
  ...

  public event Action<ViewModelBase, Action<bool?>> Navigate;

  protected virtual void OnNavigate(ViewModelBase vm, Action<bool?> callback)
  {
    Navigate?.Invoke(vm, callback);
  }
}

显然,可能还有更多的重载,其他参数,EventArgs等.我可能也应该将其放入界面中.到目前为止,这只是一个想法".

Obviously, there could be more overloads, other parameters, EventArgs and so on; and I should probably put this into an interface as well. But it's just a 'thought' so far.

在创建视图实例时(通过解析或例如在NavigationService中,请参见下文),我可以让NavigationService订阅该事件并调用回调. 这是一个有问题/不好的主意吗?这样做的缺点是什么?到目前为止(没有进行大量测试),我不喜欢的一件事是,在打开对话框后无法继续下一行,而必须在回调代码中继续进行.这也使得通过阅读代码来遵循程序流程变得更加困难.

When creating a view instance (either via resolving or e.g. in the NavigationService, see below), I can let a NavigationService subscribe to that event and invoke the callback. Is this a problematic/bad idea? What are the cons of this? So far (without testing much), one thing I don't like is that I cannot continue in the next line after opening the dialog, but have to continue inside the callback code. That also makes it harder to follow the program flow by reading the code.

任何输入都将不胜感激!这是一个非常有趣的话题,并且由于对SO的这些问题有很多答案已经过时,我希望了解有关当前最佳实践的更多信息:)

Any input is greatly appreciated! This is a very interesting topic, and since many many answers to these questions on SO are quite dated, I hope to learn more about the current best practices :)

推荐答案

为什么将实现IDialogService的类注入到视图模型中会滥用IoC?我认为这是执行此操作的好方法.

Why injecting class implementing IDialogService into the viewmodels abuses IoC? I think it's a good way to do this.

不要想太多,将视图和逻辑项目分开是个好主意,只要使用适合您的方法即可.

Don't overthink this, separating views and logic projects is a good idea, just use whatever works for you.

在上一个项目中,我使用了ReactiveUI框架中的Interaction类.它可以很好地与对话框和文件选择器一起使用.我认为它与您的选择非常相似,您可以检查代码示例.

In my last project I have used Interaction class from ReactiveUI framework. It works well with dialogs and file pickers. I think it closely resembles your alternative, you can check the code and examples.

它正在使用Reactive Extensions,但您应该了解一下.

It's using Reactive Extensions, but you should get the idea.

这篇关于视图模型的单独项目可以“强制"执行模型. MVVM:如何打开对话框?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆