首页 > 解决方案 > 从不同窗口的视图模型调用窗口中的函数

问题描述

所以,我目前有 2 个窗口(主窗口、子窗口)和一个视图模型。MainWindow 主要只是一个使用hardcodet.wpf.taskbarnotification.taskbaricon. 单击此任务栏图标的上下文菜单中的按钮会打开子窗口。

SubWindow 的 DataContext 设置为视图模型。子窗口允许用户输入一堆数据并单击“上传”按钮,这会将所有这些数据发送到我之前编写的服务。该服务将对数据执行许多操作并返回单个字符串。我目前的目标是获取这个返回的字符串并在 MainWindow 中使用它,但这是我的问题所在。

对服务的调用是在 ViewModel 中完成的,我不确定如何将响应返回到 MainWindow。我最初的想法是只引用其他对象中的每个对象(即引用 SubWindow 中的 MainWindow 和 ViewModel 中的 SubWindow),但是我宁愿避免这样做。我也考虑过事件,但是我无法弄清楚如何让事件在 ViewModel 和 MainWindow 之间工作。

任何关于我应该如何进行活动或我应该尝试做什么的帮助/建议将不胜感激。如果需要更多信息,请告诉我。

标签: c#wpf

解决方案


使用 MVVM Light Messenger

> http://dotnetpattern.com/mvvm-light-messenger
public class ViewModelA : ViewModelBase
{
    public void SearchCommandMethod()
    {
        MessengerInstance.Send<NotificationMessage>(new NotificationMessage("notification message"));
    }
}

Jesse Liberty of Microsoft has a great concrete walk through on how to make use of the messaging within MVVM Light. The premise is to create a class which will act as your message type, subscribe, then publish.

public class GoToPageMessage
{
   public string PageName { get; set; }
}
This will essentially send the message based on the above type/class...

    private object GoToPage2()
    {
       var msg = new GoToPageMessage() { PageName = "Page2" };
       Messenger.Default.Send<GoToPageMessage>( msg );
       return null;
    }

Now you can register for the given message type, which is the same class defined above and provide the method which will get called when the message is received, in this instance ReceiveMessage.

    Messenger.Default.Register<GoToPageMessage>
    ( 
         this, 
         ( action ) => ReceiveMessage( action ) 
    );

    private object ReceiveMessage( GoToPageMessage action )
    {
       StringBuilder sb = new StringBuilder( "/Views/" );
       sb.Append( action.PageName );
       sb.Append( ".xaml" );
       NavigationService.Navigate( 
          new System.Uri( sb.ToString(), 
                System.UriKind.Relative ) );
       return null;
    }

推荐阅读