为什么在使用Prism EventAggregator时未调用我的Subscribe方法? [英] Why my Subscribe method is not called when using Prism EventAggregator?

查看:298
本文介绍了为什么在使用Prism EventAggregator时未调用我的Subscribe方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习棱镜.我已经面临几个小时的问题,订阅该事件时,未调用订阅方法.我正在使用 Prism Autofac .

在下面的简化示例中,在 MainViewModel 中,在ctor中调用了Publish("dupa");事件.然后在按钮上单击 UpdateWindow .在窗口的后端创建 UpdateViewModel 的实例.

更新VM 内部运行了ctor,但是在Subscribe(UpdateName);之后,由于某些我不理解的原因,未执行 UpdateName .

完整代码:

public class MainViewModel : ViewModelBase
    {
        private IEventAggregator _eventAggregator;
        public MainViewModel(IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator; //Prism

            _eventAggregator.GetEvent<UpdateNameEvent>().Publish("dupa");

            OnOpenCommand = new DelegateCommand(OnOpenWin);
        }

        public void OnOpenWin(object obj)
        {
            UpdateWindow win = new UpdateWindow();
            win.Show();
        }

        public ICommand OnOpenCommand { get; private set; }
    }


public class UpdateViewModel : ViewModelBase
    {
        private IEventAggregator _eventAggregator;

        public UpdateViewModel(IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator; //Prism
            _eventAggregator.GetEvent<UpdateNameEvent>().Subscribe(UpdateName);
        }

        private void UpdateName(string name)
        {
            this.Name = name; //is not called at all
        }

        private string _name;
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
                OnPropertyChanged();
            }
        }
    }


public partial class UpdateWindow : Window
    {
        public UpdateWindow()
        {
            var bootStrapper = new BootStrapper();
            var container = bootStrapper.BootStrap();
            UpdateViewModel vm = container.Resolve<UpdateViewModel>();
            InitializeComponent();
            DataContext = vm;
        }
    }

更新

在调查之后,我注意到,当订阅这样的事件时,它可以正常工作:

Utility.EventAggregator.GetEvent<UpdateNameEvent>().Subscribe(UpdateName);

订阅使用已注入的 eventAggregator 时,该方法不起作用:

_eventAggregator.GetEvent<UpdateNameEvent>().Subscribe(UpdateName);

EventAggregator Autofac 注册,如下所示:

builder.RegisterType<EventAggregator>()
        .As<IEventAggregator>().SingleInstance();

我不明白为什么这种依赖性不起作用?

解决方案

我不明白为什么这种依赖性不起作用?

因为您为UpdateViewModel创建了新的EventAggregator.

var bootStrapper = new BootStrapper();
var container = bootStrapper.BootStrap();
UpdateViewModel vm = container.Resolve<UpdateViewModel>();

这似乎为UpdateWindow创建了一个新容器,并且该新容器将具有一个新的-即另一个-EventAggregator.当然,这两个不会互相发送事件.

因此解决方案是使用一个容器来解决您的所有问题.这是使用静态Utility时发​​生的情况.您应该避免使用这样的服务定位器.看一下ViewModelLocator,这可以非常轻松地为给定视图创建视图模型,或者在创建容器时将其传递给UpdateWindow(虽然也有些丑陋). /p>

I am learning Prism. Few hours already I am facing a problem, when subscribing to the event, the subscription method is not called. I am using Prism and Autofac.

In the simplified example below, in MainViewModel Publish("dupa"); event is called in the ctor. And on button click UpdateWindow is opened. In backend of the window is created instance of UpdateViewModel.

Inside of update VM ctor is ran, but after Subscribe(UpdateName); the UpdateName is not executed, because of some reason that I do not understand.

Complete code:

public class MainViewModel : ViewModelBase
    {
        private IEventAggregator _eventAggregator;
        public MainViewModel(IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator; //Prism

            _eventAggregator.GetEvent<UpdateNameEvent>().Publish("dupa");

            OnOpenCommand = new DelegateCommand(OnOpenWin);
        }

        public void OnOpenWin(object obj)
        {
            UpdateWindow win = new UpdateWindow();
            win.Show();
        }

        public ICommand OnOpenCommand { get; private set; }
    }


public class UpdateViewModel : ViewModelBase
    {
        private IEventAggregator _eventAggregator;

        public UpdateViewModel(IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator; //Prism
            _eventAggregator.GetEvent<UpdateNameEvent>().Subscribe(UpdateName);
        }

        private void UpdateName(string name)
        {
            this.Name = name; //is not called at all
        }

        private string _name;
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
                OnPropertyChanged();
            }
        }
    }


public partial class UpdateWindow : Window
    {
        public UpdateWindow()
        {
            var bootStrapper = new BootStrapper();
            var container = bootStrapper.BootStrap();
            UpdateViewModel vm = container.Resolve<UpdateViewModel>();
            InitializeComponent();
            DataContext = vm;
        }
    }

UPDATE

After investigating, I notied, that when subscribing to the events like this, it works fine:

Utility.EventAggregator.GetEvent<UpdateNameEvent>().Subscribe(UpdateName);

When subscribing with used injected eventAggregator, it does not work:

_eventAggregator.GetEvent<UpdateNameEvent>().Subscribe(UpdateName);

And EventAggregator is registered by Autofac as follows:

builder.RegisterType<EventAggregator>()
        .As<IEventAggregator>().SingleInstance();

I do not understand why this dependency does not work?

解决方案

I do not understand why this dependency does not work?

Because you create a new EventAggregator for the UpdateViewModel.

var bootStrapper = new BootStrapper();
var container = bootStrapper.BootStrap();
UpdateViewModel vm = container.Resolve<UpdateViewModel>();

This looks as if a new container is created for the UpdateWindow, and the new container will have a new - that is, a different - EventAggregator. Those two will not send events to each other, of course.

So the solution is to use one single container to resolve all your stuff. This is what happens when you use the static Utility. You should avoid using a service-locator like this. Have a look at the ViewModelLocator, which makes it really easy to create the view models for a given view, for example, or pass the container to the UpdateWindow when it is created (somewhat ugly, too, though).

这篇关于为什么在使用Prism EventAggregator时未调用我的Subscribe方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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