我有一个包含 ContentControl
的 UserControl
。ContentControl
包含ContextMenu
。我想将ContextMenu
的DataContext
设置为UserControl
的ViewModel中的属性。在这种情况下,该属性是另一个ViewModel。
以下是我的用户控制的.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 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
-这是上述UserControl
的DataContext
:
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;
}
}
最后,这是我的ConteactMenu的ViewModel:
public class ContextMenuViewModel
{
public RelayCommand SetPanModeCmd { get; set; }
public ContextMenuViewModel()
{
SetPanModeCmd = new RelayCommand(SetPanMode);
}
private void SetPanMode()
{
//stuff
}
}
我在XAML中为上述ContextMenu
所拥有的不起作用。我尝试使用RelativeSource
尝试了一些不同的变化,但没有运气。我在下面尝试过的片段:
<ContextMenu DataContext="{Binding Path=Parent.DataContext.ContextMenuViewModel, RelativeSource={RelativeSource Self}}"
<ContextMenu DataContext="{Binding DataContext.ContextMenuViewModel, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"
<ContextMenu DataContext="{Binding ContextMenuViewModel, RelativeSource={RelativeSource AncestorType=ContentControl}}"
<ContextMenu DataContext="{Binding DataContext.ContextMenuViewModel, RelativeSource={RelativeSource AncestorType=UserControl}}"
以上都没有工作。
来自Visual树的任何UIELENT都继承了父级的数据。在这种情况下,ContextMenu将MainViewModel作为DataContext将其分配给Parent ContentControl后。因此,这意味着您可以获取包括ContextMenuviewModel在内的MainViewModel的任何属性。顺便说一句,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}"
- CONTECTMENUVIEWMODEL是MainViewModel的属性的名称,而不是类型。