WPFContextMenu 控件

Posted 小林野夫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPFContextMenu 控件相关的知识,希望对你有一定的参考价值。

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"  

 

WPF ContextMenu:MenuItem 图标可见性绑定错误

【中文标题】WPF ContextMenu:MenuItem 图标可见性绑定错误【英文标题】:WPF ContextMenu: MenuItem Icon visibility binding error 【发布时间】:2017-07-23 15:54:14 【问题描述】:

这是我的 ContextMenu 的样式:

<Style x:Key="DIOStyle" TargetType="ContentControl">
        <Setter Property="Tag" Value="Binding Content,RelativeSource=RelativeSource Mode=Self"/>
        <Setter Property="ContextMenu">
            <Setter.Value>
                <ContextMenu>
                    <MenuItem Style="StaticResource DeleteMenuItemStyle"/>
                    <!--<MenuItem Header="Normality">
                        <MenuItem Style="StaticResource NcMenuItemStyle"/>
                        <MenuItem Style="StaticResource NaMenuItemStyle"/>
                    </MenuItem>-->
                    <MenuItem Style="StaticResource BothContactsMenuItemStyle"/>
                </ContextMenu>
            </Setter.Value>
        </Setter>
...

这是我的 MenuItem 的样式:

<Style x:Key="BothContactsMenuItemStyle" TargetType="MenuItem">
        <Setter Property="Header" Value="Both Contacts"/>
        <Setter Property="Command" Value="Binding PlacementTarget.Tag.BothNaNcChangeCommand,RelativeSource=RelativeSource Mode=FindAncestor,AncestorType=ContextMenu"/>
        <Setter Property="Icon">
            <Setter.Value>
                <Image Style="StaticResource Tick16Style" Visibility="Binding PlacementTarget.Tag.BothNaNc, RelativeSource=RelativeSource Mode=FindAncestor,AncestorType=ContextMenu, Converter=StaticResource BoolToVis"/>
            </Setter.Value>
        </Setter>
    </Style>

命令绑定正在工作,而不是图标可见性绑定给我这个错误:

System.Windows.Data 错误:4:找不到绑定源 参考'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ContextMenu',AncestorLevel='1''。 BindingExpression:Path=PlacementTarget.Tag.BothNaNc;数据项=空; 目标元素是'图像'(名称='');目标属性是“可见性” (类型“可见性”)

为什么? 请注意,这是有效的:

<MenuItem Header="TEST" Visibility="Binding PlacementTarget.Tag.BothNaNc, RelativeSource=RelativeSource Mode=FindAncestor,AncestorType=ContextMenu, Converter=StaticResource BoolToVis"/>

【问题讨论】:

【参考方案1】:

您可以将Image 元素定义为资源。这应该有效:

<Image x:Key="img" x:Shared="False"
               Style="StaticResource Tick16Style"
               Visibility="Binding PlacementTarget.Tag.BothNaNc, RelativeSource=RelativeSource Mode=FindAncestor,AncestorType=ContextMenu,
                            Converter=StaticResource BoolToVis"/>

<Style x:Key="BothContactsMenuItemStyle" TargetType="MenuItem">
    <Setter Property="Header" Value="Both Contacts"/>
    <Setter Property="Command" Value="Binding PlacementTarget.Tag.BothNaNcChangeCommand, RelativeSource=RelativeSource Mode=FindAncestor,AncestorType=ContextMenu"/>
    <Setter Property="Icon" Value="StaticResource img" />
</Style>

如果您将Icon 属性设置为您在&lt;Setter.Value&gt; 中定义内联的Image 元素,就像您目前所做的那样,它将从父WindowUserControl 或任何地方继承DataContext Style 已定义。

【讨论】:

以上是关于WPFContextMenu 控件的主要内容,如果未能解决你的问题,请参考以下文章

WPF ContextMenu 文本对齐

WPF ContextMenu 和 MenuItem 无法在默认样式 WPF 中设置 OverridesDefaultStyle 属性

WPF ContextMenu 在MVVM模式中绑定 Command及使用CommandParameter传参

HslControls组件库 工业控件库 曲线控件 时间控件 管道控件 温度计控件 阀门控件 传送带控件 进度条控件 电池控件 数码管控件等等

PyQt5复杂控件(树控件选项卡控件(滚动条控件多文档控件停靠控件)

父控件子控件