【WPF】ContextMenu 控件
ContextMenu无论定义在.cs或.xaml文件中,都不继承父级的DataContext,所以如果要绑定父级的DataContext,直接DataContext=“{Binding}”是行不通的
不能绑父级,但是能绑资源
第一步:定义一个中间类用来做资源对象
public class BindingProxy : Freezable { #region Overrides of Freezable protected override Freezable CreateInstanceCore() { return new BindingProxy(); } #endregion public object Data { get { return (object)GetValue(DataProperty); } set { SetValue(DataProperty, value); } } public static readonly DependencyProperty DataProperty = DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null)); }
第二步:引用命名空间,在控件中定义资源
1 <UserControl.Resources> 2 <libBinding:BindingProxy x:Key="BindingProxy" Data="{Binding}"/> 3 </UserControl.Resources>
第三步:绑定ContextMenu、MenuItem
(Button.Command 和 ContextMenu.IsOpen 的绑定部分可以不关注,这两个绑定是用来控制ContextMenu打开的)
<Button Command="{Binding Customfold}"> <Button.ContextMenu> <ContextMenu DataContext="{Binding Data,Source={StaticResource BindingProxy}}" ItemsSource="{Binding ItemModelCollection}" IsOpen="{Binding OpenCustomfold,Mode=OneWay}"> <ContextMenu.ItemContainerStyle> <Style TargetType="MenuItem"> <Setter Property="Header" Value="{Binding ...}"/> <Setter Property="Command" Value="{Binding ...}"/> <Setter Property="CommandParameter" Value="{Binding ...}"/> </Style> </ContextMenu.ItemContainerStyle> </ContextMenu> </Button.ContextMenu> <Image .../> </Button>
第四步:传递参数
ContextMenu是它自身视觉树的根节点,所以即使通过RelativeSource.FindAncestor也找不到要传递的参数。
解决:可以通过PlacementTarget解决。微软对PlacementTarget的解释是:获取或设置UIElement,当它打开时相对于它确定ContextMenu的位置。应该可以理解为放置此ContextMenu的UIElement。
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget}"
如果要传递Item,如ListBox的SelectedItem
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu},Path=PlacementTarget.SelectedItem}"
编程是个人爱好