Wpf 我可以从其他子窗口ViewModel访问主窗口ViewModel吗

Wpf 我可以从其他子窗口ViewModel访问主窗口ViewModel吗,wpf,mvvm,Wpf,Mvvm,首先,如果这很简单,我必须道歉。我是WPF和MVVM的新手,我想确保我没有违反任何WPF或MVVM概念。另外,对于下面冗长的解释(尝试给出所有细节): 我目前正在引用一个包含所有业务逻辑或服务层(服务类、实体类、数据操作等)的程序集dll 这在其他传统的Windows窗体应用程序中使用。我现在正在创建一个新的桌面WPF应用程序(早期阶段),我必须使用相同的程序集 我创建了一个带有菜单、状态栏等及其ViewModel(称为_mainViewModel)的主窗口 我用自己的ViewModel对象创建

首先,如果这很简单,我必须道歉。我是WPF和MVVM的新手,我想确保我没有违反任何WPF或MVVM概念。另外,对于下面冗长的解释(尝试给出所有细节):

我目前正在引用一个包含所有业务逻辑或服务层(服务类、实体类、数据操作等)的程序集dll

这在其他传统的Windows窗体应用程序中使用。我现在正在创建一个新的桌面WPF应用程序(早期阶段),我必须使用相同的程序集

我创建了一个带有菜单、状态栏等及其ViewModel(称为_mainViewModel)的主窗口

我用自己的ViewModel对象创建了另一个简单的窗口(称为_abcViewModel)。Windows对象/控件在子视图中绑定良好。这很有效,到目前为止我很满意

_abcViewModel使用程序集中的逻辑,这些逻辑可以使用传统的委托和事件处理程序检索某些消息

现在,我打算将来自这些事件的消息绑定到主窗口StatusBar对象,该对象绑定到_mainWindowViewModel.StatusBarItemMessage。我该怎么做

我在另一篇stackoverflow文章(:)中发现,您可以通过以下方式访问主窗口对象: ((MainWindow)System.Windows.Application.Current.MainWindow)。\u mainWindowViewModel.StatusBarMessage=args.Message

我在_abcViewModel中订阅这些DLL事件处理程序:

    private void SubscribeBusinessLogicEvents()
    {
        _SPPIDDrawingWPFService.PidToolBoxInfoEvent += new SPPIDDrawingWPFService.PidToolBoxInfoEventHandler(PidToolBoxInfoEvent);
        _SPPIDDrawingWPFService.PidToolBoxErrorEvent += new SPPIDDrawingWPFService.PidToolBoxErrorEventHandler(PidToolBoxErrorEvent);
    }


    private void UnsubscribeBusinessLogicEvents()
    {
        _SPPIDDrawingWPFService.PidToolBoxInfoEvent -= PidToolBoxInfoEvent;
        _SPPIDDrawingWPFService.PidToolBoxErrorEvent -= PidToolBoxErrorEvent;

    }


    internal void PidToolBoxErrorEvent(object sender, PidToolBoxEventArg args)
    {
        App.WriteLocalErrorLogFile(args);
    }


    internal void PidToolBoxInfoEvent(object sender, PidToolBoxEventArg args)
    {
        //Is this correct? Can I change Main Windows view model from here?
        ((MainWindow)System.Windows.Application.Current.MainWindow)._mainWindowViewModel.StatusBarItemMessage = args.Message;
        if (args.OptionalPopUpFlag)
        {
            //
        }
        App.WriteWoodEngSysToolBoxErrorLog(args);
    }
这是正确的方法吗?从其他ViewModels访问ViewModels是否打破了Model–view–viewmodel或MVVM的概念

如何根据从子窗口执行的操作更新主窗口状态栏控件。我不希望在所有窗口中都有一个巨大的ViewModel对象

如有任何帮助/建议,将不胜感激。
谢谢

查看事件聚合。您的MainWindowViewmodel应该订阅AbcViewModel广播的“事件”。这将使AbcViewModel与MainWindowViewModel分离

是实现此模式的库。对于您的需求来说,这个库可能有些过分,但是您可以轻松地实现自己的系统

您的用法可能类似于:

AbcViewModel.cs

 internal void PidToolBoxInfoEvent(object sender, PidToolBoxEventArg args)
 {
        _eventAggregator.GetEvent<PidToolBoxUpdateEvent>().Publish(args);

        App.WriteWoodEngSysToolBoxErrorLog(args);
  }
public class MainWindowViewModel
{
    public MainWindowViewModel(IEventAggregator ea)
    {
        // You may need to subscribe on the UI thread. 
        // If so, use: Subscribe(..., ThreadOption.UIThread) 
        ea.GetEvent<PidToolBoxUpdateEvent>().Subscribe(UpdateStatusBar);
    }

    void UpdateStatusBar(PidToolBoxEventArg pidEventArgs)
    {
        //implement logic
    }
}
内部无效PidToolBoxInfoEvent(对象发送方,PidToolboxEventArgs)
{
_eventAggregator.GetEvent().Publish(args);
App.WriteWoodEngSysToolBoxErrorLog(args);
}
MainWindowViewModel.cs

 internal void PidToolBoxInfoEvent(object sender, PidToolBoxEventArg args)
 {
        _eventAggregator.GetEvent<PidToolBoxUpdateEvent>().Publish(args);

        App.WriteWoodEngSysToolBoxErrorLog(args);
  }
public class MainWindowViewModel
{
    public MainWindowViewModel(IEventAggregator ea)
    {
        // You may need to subscribe on the UI thread. 
        // If so, use: Subscribe(..., ThreadOption.UIThread) 
        ea.GetEvent<PidToolBoxUpdateEvent>().Subscribe(UpdateStatusBar);
    }

    void UpdateStatusBar(PidToolBoxEventArg pidEventArgs)
    {
        //implement logic
    }
}
公共类MainWindowViewModel
{
公共主窗口视图模型(IEventAggregator ea)
{
//您可能需要在UI线程上订阅。
//如果是,请使用:Subscribe(…,ThreadOption.UIThread)
ea.GetEvent().Subscribe(UpdateStatusBar);
}
void UpdateStatusBar(PidToolBoxEventArg pidEventArgs)
{
//实现逻辑
}
}

哇,太快了。非常感谢Michael的快速回复。我将了解Prism事件聚合,并了解它是如何工作的。我今天已经做完了,但我明天会看一看,然后再回来找你。谢谢你,迈克尔。这条鳄鱼为我工作。我必须在AbcViewModel中使用BackgroundWorker来执行GetEvent(xxx).Publish(Args)。现在它很清新。我所做的是:1。-在App.xaml.cs中创建了静态的主IEventagegrator对象。2.-将EventAggregator对象传递给两个viewModels构造函数3.-订阅程序集事件处理程序并在backgroundWorker中执行该过程。。。问题。我可以直接从模型与静态ea交互,而不是通过构造函数传递它吗?或者这会违反MVVM的理念?对不起,我之前的评论问题令人困惑。我试图询问是否可以从ViewModels访问静态EventAggregator对象(在App.xaml.cs中创建),而不是将其传递给ViewModels的构造函数?或者这是对MVVM的反对。谢谢你,迈克尔。非常感谢您可以通过静态构造函数提供一个单例实例——不过,最好利用依赖项注入进行测试。别忘了接受这个回答:)谢谢迈克尔。我接受了回答。然而,由于我是新来的,我没有足够的声誉来投票赞成答案是有用的。。。。不要介意。。。非常感谢你的帮助