在MVVM应用程序中切换ViewModel时出现BindingExpression路径错误

Wil*_*ull 7 c# wpf mvvm .net-3.5

首先,一些背景.如果您熟悉该问题,请跳至该BindingExpression部分.这是我在WPF中的第一个主要项目,所以我对MVVM模式还很陌生.是我发现的唯一一个类似的问题,其黯淡的回答并没有让我感到非常兴奋.

我/我正在构建一个.NET 3.5 WPF应用程序,我正在使用MVVM(自己实现,没有框架).在此,我有一些ViewsViewModels.这些驻留在主内ApplicationViewApplicationViewModel分别.

我改变视图的方式是通过使用XAML DataTemplate元素ApplicationView,如下所示:

<DataTemplate DataType="{x:Type viewmodels:InitViewModel}">
    <views:InitView />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

然后在主体中我有一个ContentControl,它绑定到一个属性 ApplicationViewModel

<ContentControl Content="{Binding CurrentPageViewModel}"/>
Run Code Online (Sandbox Code Playgroud)

当我运行应用程序时,所有这些似乎工作正常,并完全符合预期.但是,当我在运行后查看Debug输出时,会出现很多BindingExpression错误.

这是一个例子.我有一个属性SplashText,在我的InitViewModel.这绑定到初始屏幕(InitView)中的文本块.当启动画面结束并切换视图模型时,我得到以下内容:

System.Windows.Data Error: 39 : BindingExpression path error: 'SplashText' property not found on 'object' ''MainMenuViewModel' (HashCode=680171)'. BindingExpression:Path=SplashText; DataItem='MainMenuViewModel' (HashCode=680171); target element is 'TextBox' (Name='FeedBackBox'); target property is 'Text' (type 'String')

我知道这是因为绑定仍然存在,但DataContext的CurrentPageViewModel属性已更改.所以我想知道的是:

  • 这是一个稍纵即逝的问题,即在不使用时处理的视图还是它们(以及坏的绑定)无限期地存在于内存中?
  • 有没有办法在视图处于非活动状态时清理或停用这些绑定?
  • 如果单独留下这些内容,它会对我的应用程序产生什么样的性能影响呢?
  • 是否有更好的方法来切换视图以避免此问题?

在此先感谢,并为整体问题道歉.

编辑03/09/13 - 感谢Jehof,Francesco De Lisi和Faster Solutions指出设置子视图datacontext是没有意义的,{Binding DataContext.CurrentPageViewModel, RelativeSource={RelativeSource AncestorType={x:Type Window}}}因为ContentControl负责datacontext.

Fra*_*isi 1

看起来您DataContext去了MainMenuViewModel,而您的财产属于另一个,ViewModel从而产生了错误。

CurrentPageViewModel切换视图时,启动屏幕前后的值会发生变化Binding

问题是由于DataContext="{Binding DataContext.CurrentPageViewModel, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"

事实上,CurrentPageViewModel = InitViewModel当您的应用程序启动时,问题是每个应用程序都View具有相同的DataContext(即InitViewModel首先),但我确信还ViewModels没有满足视图绑定所需的整个属性池。举个例子来理解:

ViewX绑定到PropertyX,在 中管理ViewModelXViewY绑定到PropertyY,在 中管理ViewModelY。都有DataContext = CurrentViewModel

在启动时CurrentViewModel = ViewModelX, ViewX 和 ViewY 都有DataContext = ViewModelX。但这是错误的!并且可能会产生错误。

我通常做的是在 View 类中设置 DataContext(如果您愿意,可以使用 cs 或 XAML)以及相应的 View Model,以确保它适合。然后,当需要时,我会在每次切换页面时调用刷新方法来更新我的值。如果您有共享属性,请考虑使用模型来集中您的信息(和值)。

来自http://wildermuth.com/images/mvvm_layout.png的示例图像

在此输入图像描述

显然,视图是主窗口包装的控件。

希望它是清楚的。