1

我有一个接口 IScreenViewModel,为了简化问题,我可以

RedScreenViewModel : IScreenViewModel
GreenScreenViewModel : IScreenViewModel

等等。这意味着我有一个 RedScreenView.xaml,它创建了一个 RedScreenViewModel 实例,同样适用于所有后续的彩色屏幕。

IScreenViewModel has some properties that you must implement e.g. 
interface IScreenViewModel
{
   public Color ScreenColor{get;set;}
}

我有一个 ViewmodelWrapper 类,它包含所有视图模型实例。ScreenViewModels、MenuViewModels 等...因为我使用的是 DevExpress,我无法直接在 Main.xaml.cs 文件中绑定 DataContext,原因我还不知道。所以以 main 为例。我不能拥有

ScreenLabel.DataContext  = viewModelWrapper.ScreenViewModel

我必须主要做:

DataContext  = viewModelWrapper;

这样父窗口就可以看到所有的子元素。

在 RedScreenView.xaml 我可以有这样的东西:

<Label Background="ScreenViewModel.ScreenColor"/>

希望数据绑定应该在 ViewModelWrapper 中查找 IScreenViewModel.ScreenViewModel 对象并使用动态绑定/多态性使用正确的 ScreenColor 对象。

在某些情况下,屏幕可以有更多属性,所以在 GreenScreenViewModel 中,继承 ScreenColor 属性,它可以有自己的属性DifferentProperty

问题是:我有一个工厂,它根据用户想要的屏幕返回一个屏幕对象。它返回正确的屏幕对象,但是当它通知 View 更新自身时,它会查看新对象但使用错误的 XAML。如果那有意义的话。我在 ViewModelWrapper 方法中做了类似的事情。

MainGui.ScreenWrapper.LayoutRoot.Clear() ;
MainGui.ScreenWrapper.Items.Clear() ;
MainGui.ScreenWrapper.LayoutRoot.Add(screenFactory.GetSelectedScreen("RedScreen").GetLayoutRoot()
    MainGui.UpdateLayout() ;
    ScreenViewModel = screenFactory.GetSelectedScreen("RedScreen").GetViewModel() ;

忽略我两次调用工厂的事实...... ScreenWrapper 是保存屏幕的 LayoutGroup 。当我使用该代码交换视图(屏幕)时,我希望它会使用正确的绑定。所以假设我从 GreenScreenViewModel 切换到 RedScreenViewModel,记住 GreenScreenViewModel 比 RedScreenViewModel 多一个属性,在 GreenScreenView 中我有这样的东西:

<Label Content="ScreenViewModel.DifferentProperty"/> 

当交换完成并且 ScreenViewModel 通知它现在指向 RedScreenViewModel 时,它会引发异常。我强烈假设这是因为 Layout 没有被刷新并且它仍然使用错误的视图。调试模式下的输出错误是“在 viewModelWrapper.ScreenModel 中找不到属性 DifferentProperty”这是不对的,因为我已经删除了那个 GreenScreenView,我更新了布局,我知道有一个 LayoutChanged 事件或类似的东西,所以可以也被提出了为什么它仍然看到错误的视图?如何更新 ScreenWrapper.LayoutRoot 以使用不同的绑定代码“查看”新视图。天哪,我希望这很清楚。编辑:迈克尔感谢您的回复。是的,有一个实际的例外 - “NullReferenceException” 在我正在使用的第三方 dll 中。那是因为它找不到该属性。我确定我没有说清楚,但也许问题应该是:从可视化树中删除和插入用户控件时-如何刷新可视化树以查看新绑定?如果我可以刷新可视化树,它应该可以解决我的问题。更新布局()不起作用

编辑:迈克尔感谢您的回复。是的,我正在使用的第三方 dll 中有一个实际的异常 - “NullReferenceException”。那是因为它找不到该属性。当我调用 OnPropertyChanged 时它会引发异常,并且处理程序不为空!我确定我没有说清楚,但也许问题应该是:从可视化树中删除和插入用户控件时-如何刷新可视化树以查看新绑定?如果我可以刷新可视化树,它应该可以解决我的问题。UpdateLayout() 不起作用。

4

1 回答 1

0

首先,你说

因为我使用的是 DevExpress,所以我无法直接在 Main.xaml.cs 文件中绑定 DataContext,原因我还不知道。

快递不应该是这里的问题。您需要绑定一些东西来返回适当的 ViewModel。在这里查看有关此主题的讨论。

其次,你说的错误是

在 viewModelWrapper.ScreenModel 中找不到属性 DifferentProperty

这不一定是问题,也不会导致异常。当您动态更改绑定时,INotifyPropertyChanged 事件会四处飞散,并且可能会有一段时间的“不确定性”。我假设您的 ViewModel 实现了 INotifyPropertyChanged。

我认为关键可能是仔细查看异常,如果有的话(因为“找不到属性”是调试消息,而不是异常)。为了清楚起见,您可能需要按照此处所述关闭绑定消息。如果有实际异常,请编辑详细信息。

于 2012-06-26T02:10:53.367 回答