返回首页

长话短说
您可能已经知道ContextMenu类是不是WPF可视化树的一部分(这会导致一些问题看到{A})。
尽管如此,ContextMenu中获得它的父控件的DataContext({A2})。问题是,本次收购只发生一次。如果父进程的数据环境的变化,在以后的时间,在ContextMenu的数据上下文将不会被更新。如果上下文菜单绑定到变量的东西,像一个ListBox选定的项目,这将导致问题。解决方法
解决方法是,父母的如下的DataContext显式绑定"菜单上的数据上下文:

<ContextMenu DataContext="{Binding PlacementTarget.DataContext, 

	RelativeSource={RelativeSource Self}}" >

这种神奇的法术告诉WPF创建一个菜单的数据上下文和其quot之间的永久绑定;安置targetquot;(即母公司)的数据的背景下,继续工作,甚至改变后,母公司的数据上下文。只有当您期望父进程的数据上下文在母公司的生活改变,你需要这个咒语。样品{A3}是一个Visual Studio 2010解决方案。{S0}
我创建了一个简单的示例,说明了这个问题。它包含了与国名和两个用户控件的列表框:quot; goodquot;和quot; badquot;这两个控件显示国家的首都。他们也有右键菜单显示国家的语言。良好的控制,显示正确的语言,所选国家。不好控制显示菜单时,首先调用正确的语言,然后一直显示语言,即使选定的国家的变化。
会出现这种情况,因为菜单上右键单击创建的第一,然后从母公司获得的数据上下文(正确)。在随后右键点击,重复使用相同的菜单对象(证明由quot; quot;相同的菜单命令),其数据上下文永远不会改变,除非我们为它创建一个显式绑定。
下面是一些代码的关键件(某些细节,包括quot;相同menuquot;命令为清晰起见,省略):{C}
<!-- MainWindow.xaml -->

<Window Title="MainWindow" Height="350" Width="525">

    <DockPanel LastChildFill="True">

        <ListBox Name="CountryList" ItemsSource="{x:Static local:Countries.List}" />

        <UniformGrid Rows="2" Columns="1" DataContext="{Binding SelectedItem, 

		ElementName=CountryList}">

            <local:GoodControl />

            <local:BadControl />

        </UniformGrid>

    </DockPanel>

</Window>

        

<!-- GoodControl.xaml -->

<UserControla x:Class="ContextMenuDataContext.GoodControl">

    <UserControl.Resources>

        <local:LanguageCommand x:Key="LanguageCommand" />

    </UserControl.Resources>

    <UserControl.ContextMenu>

        <ContextMenu DataContext="{Binding PlacementTarget.DataContext, 

		RelativeSource={RelativeSource Self}}" >

            <MenuItem Header="Language" Command="{StaticResource LanguageCommand}" 

		CommandParameter="{Binding Language}" />

        </ContextMenu>

    </UserControl.ContextMenu>

    <TextBlock Text="{Binding  Capital}" />

</UserControl>



<!-- BadControl.xaml -->

<UserControl x:Class="ContextMenuDataContext.BadControl">

    <UserControl.Resources>

        <local:LanguageCommand x:Key="LanguageCommand" />

    </UserControl.Resources>

    <UserControl.ContextMenu>

        <ContextMenu>

            <MenuItem Header="Language" Command="{StaticResource LanguageCommand}" 

		CommandParameter="{Binding Language}" />

        </ContextMenu>

    </UserControl.ContextMenu>

    <TextBlock Text="{Binding Capital}" />

</UserControl />
结论
数据上下文绑定的默认机制的工作原理以及在大多数情况下,因为大多数的意见永远不会改变他们的生活期间的数据上下文。如果数据环境的变化的问题​​开始。最讨厌的问题是,即使数据环境的变化,一切都将工作在第一时间调用菜单。然而,陈旧数据的后续调用将返回。这可能会很长一段时间被忽视。明确绑定上下文菜单中的数据上下文PlacementTarget.DataContext避免这种错误。历史2011年2月,27日:战后初期

回答

评论会员:罗伯特哈恩 时间:2012/01/27
你的文章使我非常了解这个疯狂的错误/功能

罗伯特
评论会员:游客 时间:2012/01/27
wisodev:感谢伟大的文章,它帮助了我很多
标记Cranness
评论会员:游客 时间:2012/01/27
我有同样的问题,和我的解决方案后,一些脑强攻是一个ContextMenu_Opened的事件处理程序设置的DataContext从PlacementTarget.DataContext。然后,我googled"DataContext的PlacementTarget",不知道如果有人发现了同样的问题,出了相同的解决方案,并发现您的文章!我删除了ContextMenu_Opened的,用你的方法(谢谢),这是更好的