【发布时间】:2013-12-31 06:56:43
【问题描述】:
我有一个MainWindow.xaml,其中DataContext 设置为MainWindowViewModel.cs。在用户单击按钮并将MyUserControl.xaml 添加到窗口之前,此窗口中没有任何内容。 MyUserControl.xaml 有一个 MyUserControlViewModel.cs 设置为 DataContext。
我想在MyUserControlViewModel.cs 中触发一个被MainWindowViewModel.cs 捕获的事件。
到目前为止,我有这个。在我的MyUserControlViewModel.cs
public event EventHandler<LoadingEventArgs> LoadingEvent;
(...)
public void MyFunction() {
LoadingEvent(this, EventLibrary.LoadingEvent(2));
}
在我的MainWindowViewModel.cs
private MyUserControlViewModel _myUserControlViewModel;
public MyUserControlViewModel _MyUserControlViewModel {
get { return _myUserControlViewModel; }
private set { _myUserControlViewModel = value; OnPropertyChangedEvent("MyUserControlViewModel"); }
}
public MainWindowViewModel() {
// Can't attach event here
}
public void AddEventToUserControl() {
_MyUserControlViewModel = new MyUserControlViewModel();
_MyUserControlViewModel.LoadingEvent += MyUserControlViewModel_LoadingEvent;
}
private void MyUserControlViewModel_LoadingEvent(object sender, LoadingEventArgs e) {
MessageBox.Show("I got here!");
}
消息"I got here" 永远不会显示,因为MyUserControlViewModel.cs 中的LoadingEvent 是null。
我只在MainWindowViewModel() 函数之外附加MyUserControlViewModel_LoadingEvent 的原因是因为在加载窗口时不会添加MyUserControl.xaml,而是在用户单击按钮之后才添加。
我认为这里的问题是事件没有与MyUserControlViewModel.cs的创建同时添加。
我需要知道如何通过代码动态创建 ViewModel 来触发冒泡事件。
更新 - 添加了更多信息
鉴于我的上述情况可能很简单并且缺少重要的细节,我将描述我的确切情况。
我有三种观点——祖父、父亲和儿子。对于每一个我都有一个 ViewModel 类。在我父亲中,我在 XAML 中声明了儿子,因为它是同时创建的,所以当我的 FatherViewModel 中有 SonViewModel = new SonViewModel() 时,它指向正确的位置,我可以在 @987654345 中访问我需要的所有内容@。因此,SonViewModel 中触发的任何被 FatherViewModel 监听的事件都会被捕获。
这里最重要的两个事实是,父亲和儿子都是同时创建的,而儿子是在 XAML 中创建的,如下所示:
<View:SonView DataContext="{Binding SonViewModel, Mode=OneWay}" />
这完全符合我的要求。
问题出现在祖父和父亲身上,因为他们不是同时创建的。我首先创建 GrandfatherView.xaml 并在其中关联 GrandfatherView.cs(我知道这不是 MVVM 实践,但我正在尝试在不使用 MVVM 模式的项目中实现一些 MVVM 功能)我创建 FatherView 并将其添加到Grid,像这样:
FatherView _fatherView = new FatherView();
_fatherView.DataContext = new FatherViewModel();
mainGrid.Children.Add(_fatherView);
因为我在创建GrandfatherView 并通过代码添加它并且没有特定绑定之后创建FatherView,所以当我在GrandfatherViewModel 类中创建FatherViewModel 对象时,它没有指向我在我的应用程序中看到的 FatherView 的实际 ViewModel。
我不确定如何在代码中创建绑定<View:SonView DataContext="{Binding SonViewModel, Mode=OneWay}" />,因此我可以确保属性和绑定相同,所以我在GrandfatherViewModel 中拥有的 ViewModel 对象实际上是我在我的应用程序中看到的对象,并且不是一个全新的对象。
那么,有什么建议吗?
【问题讨论】:
-
AddEventToUserControl() 中是否有错字?您的意思是 _MyUserControlViewModel 而不是 _MainContentViewModel?
-
是的,这是一个错字,感谢您的注意。
-
如果
LoadingEvent为空,则表示没有人成功订阅该事件。问题中没有提供足够的信息来说明原因。例如,我无法判断您在AddEventToUserControl中创建的MyUserControlViewModel实例是否实际分配给了控件的DataContext。 -
旁注:您或许应该查看Caliburn Micro,这是 IMO 的天赐之物。
-
@McGarnagle,确实 MyUserControlViewModel 的实例没有分配给 DataContext。如果我尝试使用该对象更改属性,则没有任何反应,所以我猜它没有指向正确的位置。