我有一个上下文菜单,通过绑定得到的菜单项(我使用MVVM模式):WPF:隐藏contextMenu当空
<ContextMenu ItemsSource="{Binding Path=ContextMenuItems}" />
这工作得很好。但是,在没有菜单项显示的情况下,我不想显示上下文菜单。有没有办法做到这一点?某种XAML触发器可能?
我试过在没有孩子的时候捕获Opened事件并关闭上下文菜单。这可以工作,但上下文菜单仍然闪烁...
我有一个上下文菜单,通过绑定得到的菜单项(我使用MVVM模式):WPF:隐藏contextMenu当空
<ContextMenu ItemsSource="{Binding Path=ContextMenuItems}" />
这工作得很好。但是,在没有菜单项显示的情况下,我不想显示上下文菜单。有没有办法做到这一点?某种XAML触发器可能?
我试过在没有孩子的时候捕获Opened事件并关闭上下文菜单。这可以工作,但上下文菜单仍然闪烁...
也许绑定到您的菜单项集合计数属性,并使用转换器来设置上下文菜单的可见性。
<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;
}
}
你可以尝试制作在能见度上Items.Count与值转换器的绑定 - 这应该防止您的菜单出现:)
如果使用Tendlon的解决方案上TreeView控件(可能是任何列表类型控件)与上下文菜单,它有问题。
下面介绍如何设置应用程序范围的样式来隐藏空的上下文菜单。
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>
您可以定义一个隐含的风格:
<Style TargetType="{x:Type ContextMenu}">
<Style.Triggers>
<Trigger Property="HasItems" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</Trigger>
</Style.Triggers>
</Style>
这应立即为您的所有上下文菜单的工作。
适合我。与Adam的回答非常相似(upvoted也是),但我比Trigger更喜欢BooleanToVisibilityConverter。明显比接受的答案更好 - 我没有经历过Meleak提到的闪烁的上下文菜单。 – 2012-12-07 18:56:14
比转换器选项更好。剩下的问题是当Items(MenuItems)不可见时,HasItems属性也是true。没有HasVisibleItems属性: - / – mamuesstack 2014-07-09 09:56:28
我想出了一个使用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));
}
好答案!我尝试触发HasItems并将false设置为false,但是当再次添加菜单项时,我在闪烁的背景菜单中获得了闪烁的背景菜单,但如果在这里不是这种情况,那么这绝对是做到这一点的方法。 – 2010-11-16 10:23:19
很高兴听到这个消息。如果没有其他需要添加,请将其标记为已回答。 – ThomasAndersson 2010-11-16 10:28:52
工作正常!谢谢Tendlon! :) – haagel 2010-11-16 11:21:38