WPF:空时隐藏 ContextMenu

发布于 2024-10-02 16:02:57 字数 271 浏览 0 评论 0原文

我有一个上下文菜单,可以通过数据绑定获取菜单项(我使用的是 MVVM 模式):

<ContextMenu ItemsSource="{Binding Path=ContextMenuItems}" />

这工作正常。但是,在没有可显示的菜单项的情况下,我根本不希望显示上下文菜单。有办法做到这一点吗?也许是某种 XAML 触发器?

我尝试捕获 Opened 事件或在没有子项时关闭上下文菜单。这有效,但上下文菜单仍然闪烁......

I have a context menu that gets menu items through databinding (I'm using the MVVM pattern):

<ContextMenu ItemsSource="{Binding Path=ContextMenuItems}" />

This works fine. However, in the cases when there are no menu items to show, I don't want the context menu to show up at all. Is there a way to accomplish this? Some kind of XAML trigger maybe?

I've tried catching the Opened event och closing the context menu when there are no children. This works but the context menu still flashes by...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

不可一世的女人 2024-10-09 16:02:57

您可以定义隐式样式:

<Style TargetType="{x:Type ContextMenu}">
    <Style.Triggers>
        <Trigger Property="HasItems" Value="False">
            <Setter Property="Visibility" Value="Collapsed" />
        </Trigger>
    </Style.Triggers>
</Style>

这应该同时适用于所有上下文菜单。

You can define an implicit style:

<Style TargetType="{x:Type ContextMenu}">
    <Style.Triggers>
        <Trigger Property="HasItems" Value="False">
            <Setter Property="Visibility" Value="Collapsed" />
        </Trigger>
    </Style.Triggers>
</Style>

This should work for all your context menus at once.

青瓷清茶倾城歌 2024-10-09 16:02:57

也许绑定到您的菜单项集合计数属性并使用转换器来设置上下文菜单的可见性。

 <ContextMenu ItemsSource="{Binding Path=ContextMenuItems}"
              Visibility="{Binding Path=ContextMenuItems.Count,Converter={StaticResource zeroToHiddenConverter}}">

public  class ZeroToHiddenConverter:IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    {
        int count = (int) value;

        if (count == 0) 
        {
            return Visibility.Hidden;
        }
        else
        {
            return Visibility.Visible;
        }
    }

Maybe bind to your menu items collections count property and use a converter to set the context menu's visibility.

 <ContextMenu ItemsSource="{Binding Path=ContextMenuItems}"
              Visibility="{Binding Path=ContextMenuItems.Count,Converter={StaticResource zeroToHiddenConverter}}">

public  class ZeroToHiddenConverter:IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    {
        int count = (int) value;

        if (count == 0) 
        {
            return Visibility.Hidden;
        }
        else
        {
            return Visibility.Visible;
        }
    }
腻橙味 2024-10-09 16:02:57

以下是如何设置应用程序范围样式来隐藏空上下文菜单。

HasItems 是 ContextMenu 本身的依赖属性,因此您可以根据该布尔值设置上下文菜单的可见性。

以下是在资源字典中执行此操作的方法:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <BooleanToVisibilityConverter x:Key="VisibilityOfBool" />

    <Style TargetType="{x:Type ContextMenu}">
        <Setter Property="Visibility" Value="{Binding HasItems, RelativeSource={RelativeSource Self}, Converter={StaticResource VisibilityOfBool}}"/>
    </Style>
</ResourceDictionary>

Below is how you can set an application wide style for hiding empty context menus.

HasItems is a dependency property on the ContextMenu itself, so you can set the context menu's visibility based on that boolean.

Here is how to do it in a resource dictionary:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <BooleanToVisibilityConverter x:Key="VisibilityOfBool" />

    <Style TargetType="{x:Type ContextMenu}">
        <Setter Property="Visibility" Value="{Binding HasItems, RelativeSource={RelativeSource Self}, Converter={StaticResource VisibilityOfBool}}"/>
    </Style>
</ResourceDictionary>
同展鸳鸯锦 2024-10-09 16:02:57

我想出了一个使用 OnContextMenuOpening 回调的 TreeView 解决方案。它可以防止 Alex G 提到的问题。如果您使用 XAML 样式折叠菜单,那么当上下文菜单为空时它不会出现,但是当您左键单击另一个项目时它会出现。

该代码查找想要打开 ContextMenu 的 TreeViewItem,如果没有项目,则将事件的 Handled 属性设置为 true。

protected override void OnContextMenuOpening(ContextMenuEventArgs e) {
     var item = FindTreeViewItem(e.OriginalSource as DependencyObject);
     var contextMenu = item.ContextMenu;
     if (contextMenu != null && !contextMenu.HasItems) {
         e.Handled = true;
     }
 }

 private TreeViewItem FindTreeViewItem(DependencyObject dependencyObject) {
     if (dependencyObject == null) {
         return null;
     }
     var treeViewItem = dependencyObject as TreeViewItem;
     if (treeViewItem != null) {
         return treeViewItem;
     }
     return FindTreeViewItem(VisualTreeHelper.GetParent(dependencyObject));
}

I came up with a solution for a TreeView that uses the OnContextMenuOpening callback. It prevents the problem Alex G mentioned. If you collapse the menu with a XAML style then it does not appear when the contextmenu is empty, however it appears afterwards when you left-click on another item.

The code looks for the TreeViewItem which wants to open the ContextMenu, and if it has no items, it sets the Handled property of the event to true.

protected override void OnContextMenuOpening(ContextMenuEventArgs e) {
     var item = FindTreeViewItem(e.OriginalSource as DependencyObject);
     var contextMenu = item.ContextMenu;
     if (contextMenu != null && !contextMenu.HasItems) {
         e.Handled = true;
     }
 }

 private TreeViewItem FindTreeViewItem(DependencyObject dependencyObject) {
     if (dependencyObject == null) {
         return null;
     }
     var treeViewItem = dependencyObject as TreeViewItem;
     if (treeViewItem != null) {
         return treeViewItem;
     }
     return FindTreeViewItem(VisualTreeHelper.GetParent(dependencyObject));
}
秋风の叶未落 2024-10-09 16:02:57

您可以尝试使用值转换器对 Items.Count 的可见性进行绑定 - 这应该会阻止您的菜单出现:)

You could try making a binding on Visibility on Items.Count with a value converter - that should prevent your menu from appearing :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文