2010-11-16 26 views
10

我有一个上下文菜单,通过绑定得到的菜单项(我使用MVVM模式):WPF:隐藏contextMenu当空

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

这工作得很好。但是,在没有菜单项显示的情况下,我不想显示上下文菜单。有没有办法做到这一点?某种XAML触发器可能?

我试过在没有孩子的时候捕获Opened事件并关闭上下文菜单。这可以工作,但上下文菜单仍然闪烁...

回答

14

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

<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; 
     } 
    } 
+0

好答案!我尝试触发HasItems并将false设置为false,但是当再次添加菜单项时,我在闪烁的背景菜单中获得了闪烁的背景菜单,但如果在这里不是这种情况,那么这绝对是做到这一点的方法。 – 2010-11-16 10:23:19

+0

很高兴听到这个消息。如果没有其他需要添加,请将其标记为已回答。 – ThomasAndersson 2010-11-16 10:28:52

+0

工作正常!谢谢Tendlon! :) – haagel 2010-11-16 11:21:38

0

你可以尝试制作在能见度上Items.Count与值转换器的绑定 - 这应该防止您的菜单出现:)

0

如果使用Tendlon的解决方案上TreeView控件(可能是任何列表类型控件)与上下文菜单,它有问题。

  1. 右键单击某个节点上没有上下文菜单项=>什么也没有发生(这是好的)
  2. 左键点击的右键菜单项出现=>上下文菜单的节点上(这是坏的)
3

下面介绍如何设置应用程序范围的样式来隐藏空的上下文菜单。

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> 
19

您可以定义一个隐含的风格:

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

这应立即为您的所有上下文菜单的工作。

+2

适合我。与Adam的回答非常相似(upvoted也是),但我比Trigger更喜欢BooleanToVisibilityConverter。明显比接受的答案更好 - 我没有经历过Meleak提到的闪烁的上下文菜单。 – 2012-12-07 18:56:14

+1

比转换器选项更好。剩下的问题是当Items(MenuItems)不可见时,HasItems属性也是true。没有HasVisibleItems属性: - / – mamuesstack 2014-07-09 09:56:28

0

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

该代码查找要打开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)); 
}