首先,一些上下文。如果您熟悉该问题,请跳至 BindingExpression
部分。这是我在 WPF 中的第一个主要项目,所以我对 MVVM 模式还是很陌生。 Here是我发现的唯一一个类似的问题,其平淡无奇的答案并没有真正打动我。
我已经/正在构建一个 .NET 3.5 WPF 应用程序并且我正在使用 MVVM(我自己实现,没有框架)。在其中,我有许多 Views
和 ViewModels
。它们分别位于主 ApplicationView
和 ApplicationViewModel
中。
我更改 View 的方法是在 ApplicationView
中使用 XAML DataTemplate 元素,如下所示:
<DataTemplate DataType="{x:Type viewmodels:InitViewModel}">
<views:InitView />
</DataTemplate>
然后在主体中我有一个 ContentControl,它绑定(bind)到 ApplicationViewModel
<ContentControl Content="{Binding CurrentPageViewModel}"/>
当我运行该应用程序时,所有这些似乎都运行良好,并且完全按照预期运行。但是,当我在运行后查看 Debug 输出时,出现了很多 BindingExpression
错误。
举个例子。我的 InitViewModel
中有一个属性 SplashText
。这绑定(bind)到初始屏幕 (InitView
) 中的文本 block 。当初始屏幕结束并且我关闭 View 模型时,我得到以下信息:
System.Windows.Data 错误:39:BindingExpression 路径错误:在“对象”“MainMenuViewModel”(HashCode=680171) 上找不到“SplashText”属性。绑定(bind)表达式:Path=SplashText; DataItem='MainMenuViewModel' (HashCode=680171);目标元素是 'TextBox' (Name='FeedBackBox');目标属性是“文本”(类型“字符串”)
我知道这是因为绑定(bind)仍然存在,但 DataContext 的 CurrentPageViewModel 属性已更改。所以我想知道的是:
- 这是一个短暂的问题吗,即 View 在不使用时是否被处理掉,或者它们(和不良绑定(bind))是否无限期地坐在内存中?
- 有没有一种方法可以在 View 处于非事件状态时清理或停用这些绑定(bind)?
- 如果我不管这些,会对我的应用程序产生什么样的性能影响?
- 有没有更好的切换 View 的方法来避免这个问题?
提前致谢,对于这个整体问题深表歉意。
编辑 03/09/13 - 感谢 Jehof、Francesco De Lisi 和 Faster Solutions 指出将 subview 数据上下文设置为 {Binding DataContext.CurrentPageViewModel, RelativeSource={RelativeSource AncestorType={ 毫无意义x:Type Window}}}
因为 ContentControl 负责数据上下文。
最佳答案
您的具体示例无法在 .NET 4.5 中重现,这可能意味着 Microsoft 已同时修复了该问题。
然而,当 Content 和 ContentTemplate 都是数据绑定(bind)时,会存在类似的问题。我将解决这个问题,如果有人仍在使用它,它也可能解决 .NET 3.5 中的问题。例如:
<ContentControl Content="{Binding Content}" ContentTemplate="{Binding Template}" />
或者当 ContentTemplate 由 DataTrigger 决定时:
<ContentControl Content="{Binding Content}">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding Choice}" Value="1">
<Setter Property="ContentTemplate" Value="{StaticResource TemplateA}" />
</DataTrigger>
<DataTrigger Binding="{Binding Choice}" Value="2">
<Setter Property="ContentTemplate" Value="{StaticResource TemplateB}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
在这两种情况下,都会出现类似于 OP 观察到的绑定(bind)错误。
这里的技巧是确保以正确的顺序执行对 Content 和 ContentTemplate 的更改,以防止绑定(bind)错误。我写了DelayedContentControl ,这确保了 Content 和 ContentTemplate 同时以正确的顺序更改。
<jc:DelayedContentControl Content="{Binding Content}" ContentTemplate="{Binding Template}">
与 DataTrigger 情况类似。
您可以从我的开源中获取 DelayedContentControl JungleControls library .
关于c# - 在 MVVM 应用程序中切换 ViewModel 时出现 BindingExpression 路径错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18517201/