ContextMenu命令绑定未随数据源更新

ygo*_*goe 3 wpf binding command

在我的WPF应用程序中,有一个列表可供选择。然后,所选项目将显示在ContentControl中以进行进一步的交互。根据所选项目的类型(可以有多个),在ContentControl中使用适当的DataTemplate。到目前为止,对于数据处理业务应用程序来说这应该没有什么异常。

在每个DataTemplate中,都有多个TextBoxes和其他控件,这些控件将其值绑定到ViewModel类的特定属性。从列表中选择另一个项目时,所有这些都将按预期更新。这些按钮还会在ViewModel的正确实例上执行其命令。

有一个上下文菜单项也可以执行命令,但这仅适用于第一个选定的项。当从列表中选择另一个相同类型的元素时,重新使用已经加载的模板视图,上下文菜单中的命令将始终在第一个选择的项目上执行。因此,绑定未更新为ViewModel的正确实例。

使菜单项使用正确的ViewModel实例的唯一方法是选择其他类型的项,以便将模板更改为另一个视图。只有这样,上下文菜单才能正确更新。

为什么菜单项命令不会像视图中的其他绑定一样被更新?它在加载时被提取一次,但在视图的生命周期中从未更新过。

ygo*_*goe 5

不是Command绑定不会更新,而是DataContext已过期。一旦知道正确的搜索词,这就是一个广为人知的问题...

以下是带有更多链接的说明:

http://www.codeproject.com/Articles/162784/WPF-ContextMenu-Strikes-Again-DataContext-Not-Upda

这是该文章的相关部分:

解决方法是将菜单的数据上下文显式绑定到父级的数据上下文,如下所示:

<ContextMenu DataContext="{Binding PlacementTarget.DataContext,
    RelativeSource={RelativeSource Self}}">
Run Code Online (Sandbox Code Playgroud)

这个神奇的咒语告诉WPF在菜单的数据上下文与其“放置目标”(即父对象)数据上下文之间创建永久绑定,即使在更改父对象的数据上下文之后,该绑定仍继续起作用。仅当您期望父级的数据上下文在父级生命周期中发生变化时,才需要此咒语。

我之前发现的另一个解决方案是在Opened事件中将上下文菜单的DataContext手动设置为窗口的DataContext。这需要在代码隐藏文件中添加其他C#代码,并且可能需要适应不同的情况。因此,我认为上面的仅XAML方式更好。