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

标签 c# wpf mvvm .net-3.5

首先,一些上下文。如果您熟悉该问题,请跳至 BindingExpression 部分。这是我在 WPF 中的第一个主要项目,所以我对 MVVM 模式还是很陌生。 Here是我发现的唯一一个类似的问题,其平淡无奇的答案并没有真正打动我。

我已经/正在构建一个 .NET 3.5 WPF 应用程序并且我正在使用 MVVM(我自己实现,没有框架)。在其中,我有许多 ViewsViewModels。它们分别位于主 ApplicationViewApplicationViewModel 中。

我更改 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/

相关文章:

c# - GetHashCode 在 .NET 中的 IEqualityComparer<T> 中的作用是什么?

wpf - 通过静态属性而不是静态字段公开 DependencyProperty 的主要缺点是什么? (F#)

c# - 使用 MVVM 在组合框中设置默认值

c# - 如何从 View 模型中显示自定义窗口,它们都位于单独的程序集中?

c# - 将变量传递给 catch block

c# - 启动与文件关联的外部进程并将此应用程序发送到后台

c# - FileSystemWatcher 和最后一行文本文件

wpf - 如何在 WPF 中提供字符串文字值作为绑定(bind)

c# - 在自定义数据对象中使用数组 (WPF C#)

c# - WPF 绑定(bind)不更新 View