WPF - 如果命令的CanExecute为false,如何隐藏菜单项?

Gus*_*nti 49 wpf command contextmenu menuitem

默认情况下,菜单项在无法执行命令时会被禁用(CanExecute = false).根据CanExecute方法使菜单项可见/折叠的最简单方法是什么?

谢谢

为方便起见,这里的解决方案是:使用"Boolean to Visibility"转换器将visibility属性绑定到IsEnabled属性.

Red*_*dog 52

谢谢你的解决方案.对于那些想要显式XAML的人来说,这可能有所帮助:

<Window.Resources>
        <BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter" />
</Window.Resources>

<ContextMenu x:Key="innerResultsContextMenu">
    <MenuItem Header="Open"
              Command="{x:Static local:Commands.AccountOpened}"
              CommandParameter="{Binding Path=PlacementTarget.DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}" 
              CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"
              Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource booleanToVisibilityConverter}}" 
              />
</ContextMenu>
Run Code Online (Sandbox Code Playgroud)

在我的例子中,上下文菜单是一个资源,因此可见性的绑定必须使用RelativeSource自我绑定设置.

作为一方,对于CommandParameter,您还可以传递单击项目的DataContext以打开上下文菜单.并且为了将命令绑定路由到父窗口,您还需要相应地设置CommandTarget.


rja*_*ong 45

<Style.Triggers>
    <Trigger Property="IsEnabled" Value="False">
        <Setter Property="Visibility" Value="Collapsed"/>
    </Trigger>
</Style.Triggers>
Run Code Online (Sandbox Code Playgroud)

CanExecute切换IsEnabled属性所以只需观察它并将所有内容保存在UI中.如果要重复使用,请创建单独的样式.

  • 可见性应设置为"折叠",否则隐藏的菜单项仍将占用空间. (7认同)

MrD*_*osu 43

您可以简单地将Visibility绑定到IsEnabled(在CanExecute == false时设置为false).你仍然需要一个IValueConverter来将bool转换为visible/collapsed.

    public class BooleanToCollapsedVisibilityConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            //reverse conversion (false=>Visible, true=>collapsed) on any given parameter
            bool input = (null == parameter) ? (bool)value : !((bool)value);
            return (input) ? Visibility.Visible : Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
Run Code Online (Sandbox Code Playgroud)

  • 这比使用触发器所需的工作量要多得多 (4认同)