WPF MVVM 从 VIEW MODEL 获取父级

Posted

技术标签:

【中文标题】WPF MVVM 从 VIEW MODEL 获取父级【英文标题】:WPF MVVM Get Parent from VIEW MODEL 【发布时间】:2011-02-15 05:05:34 【问题描述】:

在 MVVM WPF 应用程序中。

如何从ViewModel 设置第二个 Windows 父级?

示例:

view1 -- viewModel1

viewModel1的命令调用:

var view2 = new view2

view2.Owner = viewModel 获得 view1 作为这里的所有者?

view2.Show()

编辑:

请参阅下面接受的答案,然后阅读以下编辑。

我正在使用 MVVM 灯 -> http://mvvmlight.codeplex.com/(真棒顺便说一句)

内置的消息传递系统非常棒。我现在从视图模型向我的视图发送一条消息,告诉它显示另一个窗口。

对于消息,我目前在主视图中使用带有 switch 语句的字符串来确定要打开的视图;但是,我可能会修改也属于 MVVM 轻量级工具包的令牌。

谢谢!

【问题讨论】:

嗨 dnndeveloper,当你说你正在从 viewmodel 发送消息到 view 告诉它显示另一个窗口时,你的意思是你正在接收该消息并在 view1 代码后面创建/显示另一个窗口?跨度> nabeelfarid - 是的,在后面的代码中接收到消息,然后在解析消息后,它将显示相应的窗口。 【参考方案1】:

Prism-Event Aggrigator 是一个很好的方法,我们可以在其中创建没有依赖关系的独立模块。第一个视图模型将发布事件,然后另一个视图或视图或视图模型可以从事件聚合器订阅该事件。

在这种情况下,Unity 容器也可以使用依赖注入将一个视图模型注入到另一个视图模型中。

【讨论】:

【参考方案2】:

您可以这样做,就像您需要创建一些事件并在视图中注册这些事件并在视图模型中调用它们。然后打开该弹出窗口。

喜欢这个例子

public class Mainclass : MainView

  public delegate abc RegisterPopUp(abc A);
  public RegisterPopUp POpUpEvent;

  public RelayCommand ShowCommand  private set; get;   

  public void ShowCommand() 
   
    ShowCommand("Your parameter");
   

在视图中

MainView mn = new MainView();

mn.POpUpEvent +=一样在这里注册事件,然后双击tab按钮,在注册弹出方法中编写打开弹出窗口的代码。

【讨论】:

【参考方案3】:

来自您的视图模型调用

Messenger.Default.Send<NotificationMessage>(new NotificationMessage("Open Window"));

从您视图的代码隐藏(调用第二个 view) 很容易在构造函数中这样写:

Messenger.Default.Register<NotificationMessage>(this, ReplyToMessage);

并且还要在视图的代码隐藏中编写这个方法:

private void ReplyToMessage(NotificationMessage msg)

   if (msg.Notification == "Open Window")
   
      SecondWindow win = new SecondWindow();
      win.ShowDialog();
   

【讨论】:

【参考方案4】:

我没有自己的答案,但这里有一些我最近一直在看的东西的链接,它们可能会有所帮助。我也会对其他人的建议感兴趣。

据我了解,关键是,如果可能,您不应该从视图模型中创建视图,因此您需要一种以松散耦合的方式传达所需内容的方法.

http://www.codeproject.com/KB/WPF/XAMLDialog.aspx

http://www.codeproject.com/KB/architecture/MVVM_Dialogs.aspx

Handling Dialogs in WPF with MVVM

【讨论】:

【参考方案5】:

在我看来,打开一个新窗口是 View 的责任,而不是 ViewModel 的责任。就个人而言,我会使用与显示对话框相同的方法(这个论坛已经讨论过):

让 ViewModel 向 View 发送一条消息,请求它打开一个新窗口。 (或者)使用 IDialogService 或任何你想调用它的东西,你传递给 ViewModel 的构造函数。该服务将负责打开窗口(或将此任务委托给视图)。 这样,您可以保持关注点的清晰分离,并且您的 VM 仍然可测试(您可以对打开新窗口的请求进行单元测试,但您无法测试窗口是否已经打开)。

这有意义吗?

干杯,

劳伦特

【讨论】:

嗨 Laurent,我应该如何从 ViewModel1 向 View1 发送消息以打开一个新的 View2?您的意思是该消息将在 View 1 后面的代码中收到吗?因为我认为消息传递应该发生在 mvvm 中的视图模型之间。还是我完全错了。对不起,我是 mvvm 和 wpf 的新手,我正在使用你的 mvvm light 工具包。 当使用 IDialogService 打开新窗口时,我将如何设置新窗口/view2 的所有者属性,因为我需要引用 window1/view1,而 viewmodel1 不包含对 view1 的引用?所以我认为 dialogService 将通过消息传递将任务委托给 view1,我仍然不确定 view1 将如何接收消息并处理它,除非在 view1 代码隐藏中完成? 嗨 Laurent,您能否说明处理 ViewModel1 发送的消息(将创建一个新的 view2)的代码应该放在哪里?在 View1 后面的代码中? @nabeelfarid 在 LBugnion 的 MVVM 灯中有 Messenger.Default.Send 小问题,如果你创建了一个服务,而这个服务只接收一个ViewModel,那么这个服务怎么能把所有者设置为新窗口呢?

以上是关于WPF MVVM 从 VIEW MODEL 获取父级的主要内容,如果未能解决你的问题,请参考以下文章

MVVM模式被破坏了吗?

wpf 在MVVM模式下怎样在Viewmodel里面获得view的控件对象。

WPF---MVVM初尝试

从WPF中的View和View Model访问属性

MVVM模式解析和在WPF中的实现

WPF的MVVM模式