我有几个ContextMenus,其项目定义如下:
<ContextMenu>
<MenuItem Header="Item 1" Command="{Binding Item1Command}"/>
<MenuItem Header="Item 2" Command="{Binding Item2Command}"/>
<MenuItem Header="Item 3" Command="{Binding Item3Command}"/>
</ContextMenu>
Command
绑定设置了CanExecute
,因此当它为假时,MenuItem
有IsEnabled=false
。这会继续触发,在Visibility=Collapsed
时设置IsEnabled=false
,同样也会发生相反的情况。我遇到的问题是如果所有MenuItem
都被禁用,ContextMenu
仍会显示为一个小的空白矩形。我有很多ContextMenu
,那么实现这个的最模块化方法是什么?
答案 0 :(得分:0)
我最终做了一个不同的解决方法,而不是隐藏ContextMenu的可见性。它似乎效率较低,因为它检查所有FrameworkElement ContextMenus,但它正在工作:
EventManager.RegisterClassHandler(typeof(FrameworkElement), ContextMenuOpeningEvent,
new RoutedEventHandler(OnContextMenuOpening));
private void OnContextMenuOpening(object sender, RoutedEventArgs e)
{
var control = (sender as FrameworkElement);
var menu = control == null ? null : control.ContextMenu;
if (menu != null)
{
var items = menu.Items.Cast<MenuItem>();
if (items.All(i => i.Visibility != Visibility.Visible))
{
e.Handled = true;
}
}
}
如果有更好的方法可以在没有代码的情况下做到这一点,那么对于父控件来说,我仍然愿意接受其他解决方案。
答案 1 :(得分:0)
这是一段xaml,它将让你开始使用&#34; Conditional&#34;文本菜单。
请注意:这只是起点
<ListView>
<ListView.Resources>
<ContextMenu x:Key="initial">
<Menu>
<MenuItem Header="First Option"></MenuItem>
</Menu>
</ContextMenu>
<Style TargetType="ListViewItem">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="1">
<Setter Property="ContextMenu" Value="{StaticResource initial}" />
</DataTrigger>
</Style.Triggers>
<Setter Property="ContextMenu" Value="{StaticResource initial}"/>
</Style>
</ListView.Resources>
<ListViewItem>1</ListViewItem>
<ListViewItem>2</ListViewItem>
</ListView>
答案 2 :(得分:0)
我发现解决此问题的唯一方法是通过附加属性,但它对我来说似乎可以接受。首先定义一个具有属性的类:
public class ContextMenuExtension
{
public static bool GetHideOnEmpty(DependencyObject obj)
{
return (bool)obj.GetValue(HideOnEmptyProperty);
}
public static void SetHideOnEmpty(DependencyObject obj, bool value)
{
obj.SetValue(HideOnEmptyProperty, value);
}
public static readonly DependencyProperty HideOnEmptyProperty =
DependencyProperty.RegisterAttached("HideOnEmpty", typeof(bool), typeof(ContextMenuExtension), new UIPropertyMetadata(false, HideOnEmptyChanged));
private static void HideOnEmptyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var contextMenu = d as ContextMenu;
if (contextMenu == null)
return;
contextMenu.Loaded += ContextMenu_Loaded;
}
private static void ContextMenu_Loaded(object sender, RoutedEventArgs e)
{
var contextMenu = sender as ContextMenu;
var hideOnEmpty = GetHideOnEmpty(contextMenu);
HideContextMenu(contextMenu, hideOnEmpty);
}
//This is where we check if all the items are not visible
private static void HideContextMenu(ContextMenu contextMenu, bool val)
{
//First, we have to know if the HideOnEmpty property is set to true.
if (val)
{
//Check if the contextMenu is either null or empty
if (contextMenu.Items == null || contextMenu.Items.Count < 1)
contextMenu.Visibility = Visibility.Collapsed; //Hide the contextMenu
else
{
bool hide = true;
//Check if all the items are not visible.
foreach (MenuItem i in contextMenu.Items)
{
if (i.Visibility == Visibility.Visible)
{
hide = false;
break;
}
}
//If one or more items above is visible we won't hide the contextMenu.
if (!hide)
contextMenu.Visibility = Visibility.Visible;
else
contextMenu.Visibility = Visibility.Collapsed;
}
}
}
}
然后在XAML中使用ContextMenu在上面的类中添加一个名称空间,然后执行以下操作:
<ContextMenu cc:ContextMenuExtension.HideOnEmpty="True">
<MenuItem Header="Delete" Command="<delete_command>" Visibility="Collapsed"/>
</ContextMenu>
每次用户右键单击以查看菜单时,它将触发“ ContextMenuExtension”类中的“ HideContextMenu”方法,如果没有任何项或所有项都不可见-隐藏整个ContextMenu。