我一直有这个疯狂的文本菜单和其的MenuItems挣扎绕了长时间。但是我找到了一个解决方案,使用名为“Data”的依赖属性创建自定义行为“BindingProxyBehaviour”。这个属性包含一个对象,例如你的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); }
}
}
只需将BindingProxy添加为xaml文件中的资源就可以了。
<UserControl.Resources>
<ResourceDictionary>
<behaviors:BindingProxyDataBehavior x:Key="BindingProxyViewModel" Data="{Binding}"/>
<behaviors:BindingProxyDataBehavior x:Key="BindingProxyViewModelDynamicDataList" Data="{Binding DynamicDataListObject}"/>
</ResourceDictionary>
</UserControl.Resources>
在我的情况我使用CompositeCollection来混合静态和动态MenuItems。因此使用键“BindingProxyViewModelDynamicDataList”的第二个资源。
现在您可以轻松访问您的数据,无论您的ContextMenu在哪里。 我在xaml树中的ContexMenu位置是UserControl-> Grid-> DataGrid-> DataGridTemplateColumn-> CellTemplate-> DataTemplate-> TextBox.Template-> Grid-> TextBlock-> controls:IconButton(从按钮派生的简单的customButton控件),在这里我们在IconButton里面:
<controls:IconButton.ContextMenu>
<ContextMenu x:Name="AnyContextMenuName">
<ContextMenu.Resources>
<HierarchicalDataTemplate DataType="{x:Type DynamicDataListItemType}">
<TextBlock Text="{Binding DynamicDataListItemProperty}"/>
</HierarchicalDataTemplate>
</ContextMenu.Resources>
<ContextMenu.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource BindingProxyViewModelDynamicDataList}, Path=Data}"/>
<Separator/>
<MenuItem Header="Your static header" Command="{Binding Source={StaticResource BindingProxyViewModel}, Path=Data.ViewModelCommandForYourStaticMenuItem}"/>
</CompositeCollection>
</ContextMenu.ItemsSource>
<ContextMenu.ItemContainerStyle>
<Style>
<Setter Property="MenuItem.Foreground" Value="{DynamicResource DefaultForegroundBrush}"/>
<Setter Property="MenuItem.Command" Value="{Binding Source={StaticResource BindingProxyViewModel}, Path=Data.ViewModelCommandForDynamicMenuItems}"/>
<Setter Property="MenuItem.CommandParameter" Value="{Binding}"/>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</controls:IconButton.ContextMenu>
我希望我可以帮助这个短的帖子sombody。
有关如何在UserControl.Resources中使用DataGridRowContextMenu并使用Style绑定的任何建议?然后,x:Key名称在代码后面不可用。 – ferdyh 2012-07-26 11:34:09
@Ferdy在这种情况下,您可以在代码中使用[FrameworkElement.FindResource](http://msdn.microsoft.com/zh-cn/library/system.windows.frameworkelement.findresource.aspx)方法,然后使用SetNamescope;也看看我的答案[这里](http://stackoverflow.com/questions/11333028/how-to-access-a-control-from-a-contextmenu-menuitem-via-the-visual-tree/11339065#11339065 )获取相关信息。 – akjoshi 2012-07-26 15:12:03