为什么我的 Subscribe 方法在使用 Prism EventAggregator 时没有被调用?
Why my Subscribe method is not called when using Prism EventAggregator?
我正在学习 Prism。几个小时后我就遇到了一个问题,当订阅事件时,订阅方法没有被调用。我正在使用 Prism 和 Autofac.
在下面的简化示例中,在 MainViewModel Publish("dupa");
中调用了 ctor
事件。然后单击按钮 UpdateWindow 打开。在 window 的后端创建了 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();
我不明白为什么这个依赖不起作用?
I do not understand why this dependency does not work?
因为您为 UpdateViewModel
创建了一个新的 EventAggregator
。
var bootStrapper = new BootStrapper();
var container = bootStrapper.BootStrap();
UpdateViewModel vm = container.Resolve<UpdateViewModel>();
这看起来好像为 UpdateWindow
创建了一个新容器,并且新容器将有一个新的 - 即不同的 - EventAggregator
。当然,这两者不会互相发送事件。
所以解决方案是使用一个容器来解决所有问题。当您使用静态 Utility
时会发生这种情况。你应该避免像这样使用 service-locator。看一下 ViewModelLocator
,这使得为给定视图创建视图模型变得非常容易,例如,或者在创建时将容器传递给 UpdateWindow
(也有点难看,虽然)。
我正在学习 Prism。几个小时后我就遇到了一个问题,当订阅事件时,订阅方法没有被调用。我正在使用 Prism 和 Autofac.
在下面的简化示例中,在 MainViewModel Publish("dupa");
中调用了 ctor
事件。然后单击按钮 UpdateWindow 打开。在 window 的后端创建了 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();
我不明白为什么这个依赖不起作用?
I do not understand why this dependency does not work?
因为您为 UpdateViewModel
创建了一个新的 EventAggregator
。
var bootStrapper = new BootStrapper();
var container = bootStrapper.BootStrap();
UpdateViewModel vm = container.Resolve<UpdateViewModel>();
这看起来好像为 UpdateWindow
创建了一个新容器,并且新容器将有一个新的 - 即不同的 - EventAggregator
。当然,这两者不会互相发送事件。
所以解决方案是使用一个容器来解决所有问题。当您使用静态 Utility
时会发生这种情况。你应该避免像这样使用 service-locator。看一下 ViewModelLocator
,这使得为给定视图创建视图模型变得非常容易,例如,或者在创建时将容器传递给 UpdateWindow
(也有点难看,虽然)。