ContextMenu不管定义在.cs或.xaml文件中,都不继承父级的DataContext,因此若是要绑定父级的DataContext,直接DataContext=“{Binding}”是行不通的ide
不能绑父级,可是能绑资源spa
第一步:定义一个中间类用来作资源对象code
1 public class BindingProxy : Freezable 2 { 3 #region Overrides of Freezable 4 5 protected override Freezable CreateInstanceCore() 6 { 7 return new BindingProxy(); 8 } 9 10 #endregion 11 12 public object Data 13 { 14 get { return (object)GetValue(DataProperty); } 15 set { SetValue(DataProperty, value); } 16 } 17 18 public static readonly DependencyProperty DataProperty = 19 DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null)); 20 }
第二步:引用命名空间,在控件中定义资源对象
1 <UserControl.Resources> 2 <libBinding:BindingProxy x:Key="BindingProxy" Data="{Binding}"/> 3 </UserControl.Resources>
第三步:绑定ContextMenu、MenuItemblog
(Button.Command 和 ContextMenu.IsOpen 的绑定部分能够不关注,这两个绑定是用来控制ContextMenu打开的)继承
1 <Button Command="{Binding Customfold}"> 2 <Button.ContextMenu> 3 <ContextMenu DataContext="{Binding Data,Source={StaticResource BindingProxy}}" 4 ItemsSource="{Binding ItemModelCollection}" 5 IsOpen="{Binding OpenCustomfold,Mode=OneWay}"> 6 <ContextMenu.ItemContainerStyle> 7 <Style TargetType="MenuItem"> 8 <Setter Property="Header" Value="{Binding ...}"/> 9 <Setter Property="Command" Value="{Binding ...}"/> 10 <Setter Property="CommandParameter" Value="{Binding ...}"/> 11 </Style> 12 </ContextMenu.ItemContainerStyle> 13 </ContextMenu> 14 </Button.ContextMenu> 15 <Image .../> 16 </Button>
第四步:传递参数资源
ContextMenu是它自身视觉树的根节点,因此即便经过RelativeSource.FindAncestor也找不到要传递的参数。get
解决:能够经过PlacementTarget解决。微软对PlacementTarget的解释是:获取或设置UIElement,当它打开时相对于它肯定ContextMenu的位置。应该能够理解为放置此ContextMenu的UIElement。it
1 CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget}" io
若是要传递Item,如ListBox的SelectedItem:
1 CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItem}"
参考: