我已经在ContextMenu和其MenuItems上苦苦挣扎很久了。但是我找到了一种解决方案,通过创建一个名为"BindingProxyBehaviour"的自定义行为并添加一个名为"Data"的依赖属性来使用它。这个属性持有一个对象,比如你的DataContext(如果你使用MVVM模式可能是你的ViewModel)。
public class BindingProxyDataBehavior : Freezable
{
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object), typeof(BindingProxyDataBehavior), new UIPropertyMetadata(null));
protected override Freezable CreateInstanceCore()
{
return new BindingProxyDataBehavior();
}
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
}
只需在您的xaml文件中将BindingProxy添加为资源,如下所示。
<UserControl.Resources>
<ResourceDictionary>
<behaviors:BindingProxyDataBehavior x:Key="BindingProxyViewModel" Data="{Binding}"/>
<behaviors:BindingProxyDataBehavior x:Key="BindingProxyViewModelDynamicDataList" Data="{Binding DynamicDataListObject}"/>
</ResourceDictionary>
</UserControl.Resources>
在我的情况下,我正在使用CompositeCollection来混合静态和动态的菜单项。因此第二个关键字为"BindingProxyViewModelDynamicDataList"的资源。
现在,您可以轻松访问数据,无论您的ContextMenu位于何处。
我的ContexMenu在xaml树中的位置是UserControl->Grid->DataGrid->DataGridTemplateColumn->CellTemplate->DataTemplate->TextBox.Template->Grid->TextBlock->controls:IconButton(简单的自定义按钮控件派生自button),现在我们在IconButton内部:
<controls:IconButton.ContextMenu>
<ContextMenu x:Name="AnyContextMenuName">
<ContextMenu.Resources>
<HierarchicalDataTemplate DataType="">
<TextBlock Text=""/>
</HierarchicalDataTemplate>
</ContextMenu.Resources>
<ContextMenu.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection=", Path=Data}"/>
<Separator/>
<MenuItem Header="Your static header" Command=", Path=Data.ViewModelCommandForYourStaticMenuItem}"/>
</CompositeCollection>
</ContextMenu.ItemsSource>
<ContextMenu.ItemContainerStyle>
<Style>
<Setter Property="MenuItem.Foreground" Value=""/>
<Setter Property="MenuItem.Command" Value=", Path=Data.ViewModelCommandForDynamicMenuItems}"/>
<Setter Property="MenuItem.CommandParameter" Value=""/>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</controls:IconButton.ContextMenu>
我希望这篇简短的文章能够帮助到一些人。