将ContextMenu的DataContext绑定到容器的DataContext中的属性

时间:2019-05-03 23:48:54

标签: c# wpf contextmenu datacontext

我有一个UserControl,其中包含一个ContentControlContentControl包含一个ContextMenu。我想将DataContext的{​​{1}}设置为ContextMenu的视图模型中的一个属性。在这种情况下,该属性是另一个视图模型。

下面是我的用户控件的.xaml:

UserControl

以下是用户控件的代码:

<UserControl x:Class="TestProj.MainWindow"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:views="clr-namespace:OnyxWPF.Views"
             mc:Ignorable="d">
    <UserControl.Resources>
        <BooleanToVisibilityConverter x:Key="BoolToVis" />
    </UserControl.Resources>
    <Grid>
        <ContentControl Content="{Binding MainMap}">
            <ContentControl.ContextMenu>
                <ContextMenu DataContext="{Binding ContextMenuViewModel}" Visibility="{Binding IsPopUpEnabled, Converter={StaticResource BoolToVis}}" >
                    <MenuItem Header="Pan" Command="{Binding SetPanModeCmd}">
                        <MenuItem.Icon>
                            <Image Source="Images/panHand.ico" />
                        </MenuItem.Icon>
                    </MenuItem>
            </ContentControl.ContextMenu>
        </ContentControl>
    </Grid>
</UserControl>

public partial class MainWindow : UserControl { public MainWindow() { InitializeComponent(); DataContext = new MainViewModel(); } } -这是上述MainViewModel的{​​{1}}:

DataContext

最后,这是我的上下文菜单的视图模型:

UserControl

我在上述public class MainViewModel { public WpfMap MainMap { get; set; } //Content control's context is bound to this public ContextMenuViewModel ContextMenuViewModel { get; set; } //this should be the context menu's datacontext public bool IsPopUpEnabled { get; set; } //determines if the contextmenu will appear or not public MainViewModel() { MainMap = new WpfMap(); ContextMenuViewModel = new ContextMenuViewModel(); IsPopUpEnabled = true; } } 的xaml中没有任何功能。我使用public class ContextMenuViewModel { public RelayCommand SetPanModeCmd { get; set; } public ContextMenuViewModel() { SetPanModeCmd = new RelayCommand(SetPanMode); } private void SetPanMode() { //stuff } } 尝试了几种不同的变体,但是没有运气。我在下面尝试过的代码片段:

ContextMenu

以上方法均无效。

1 个答案:

答案 0 :(得分:1)

视觉树中的任何UIElement都会继承父级的DataContext。在那种情况下,在将ContextMenu分配给父ContentControl之后,它会将MainViewModel作为DataContext。因此,这意味着您可以访问MainViewModel的任何属性,包括ContextMenuViewModel。顺便说一下,WPF数据绑定支持任意数量的嵌套属性。而且您的XAML将如下所示:

    <UserControl x:Class="TestProj.MainWindow"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 xmlns:views="clr-namespace:OnyxWPF.Views"
                 mc:Ignorable="d">
         <UserControl.Resources>
             <BooleanToVisibilityConverter x:Key="BoolToVis" />
         </UserControl.Resources>
         <Grid>
             <ContentControl Content="{Binding MainMap}">
                 <ContentControl.ContextMenu>
                     <ContextMenu Visibility="{Binding IsPopUpEnabled, Converter={StaticResource BoolToVis}}">
                         <MenuItem Header="Pan" 
                                   Command="{Binding ContextMenuViewModel.SetPanModeCmd}">
                             <MenuItem.Icon>
                                 <Image Source="Images/panHand.ico" />
                             </MenuItem.Icon>
                         </MenuItem>
                     </ContextMenu>
                 </ContentControl.ContextMenu>
             </ContentControl>
         </Grid>
     </UserControl>

P.S。为了澄清:Command="{Binding ContextMenuViewModel.SetPanModeCmd}"-ContextMenuViewModel是MainViewModel属性的名称,而不是Type。