WPF-如果命令';什么是假的?

WPF-如果命令';什么是假的?,wpf,command,contextmenu,menuitem,Wpf,Command,Contextmenu,Menuitem,默认情况下,当菜单项的命令无法执行时,菜单项将被禁用(CanExecute=false)。基于CanExecute方法,使菜单项可见/折叠的最简单方法是什么?我不知道这是否是最简单的方法,但您始终可以创建一个属性,返回CanExecute(),然后将元素的可见性绑定到此属性,使用IValueConverter将布尔值转换为可见性 您只需将可见性绑定到IsEnabled(CanExecute==false时设置为false)。 您仍然需要一个IValueConverter将bool转换为可见/折叠

默认情况下,当菜单项的命令无法执行时,菜单项将被禁用(CanExecute=false)。基于CanExecute方法,使菜单项可见/折叠的最简单方法是什么?

我不知道这是否是最简单的方法,但您始终可以创建一个属性,返回
CanExecute()
,然后将元素的可见性绑定到此属性,使用
IValueConverter
将布尔值转换为可见性

您只需将可见性绑定到IsEnabled(CanExecute==false时设置为false)。 您仍然需要一个IValueConverter将bool转换为可见/折叠

    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
    }

谢谢你的解决方案。对于那些想要显式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>

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


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

Microsoft提供BooleantVisibilityConverter。



CanExecute
切换
IsEnabled
属性,因此只需查看此项并将所有内容保留在UI中即可。如果要重复使用此样式,请创建一个单独的样式。

将可见性绑定到iEnabled可以做到这一点,但所需的XAML非常长且复杂:

Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource booleanToVisibilityConverter}}"
您可以使用附加属性隐藏所有绑定细节,并清楚地传达您的意图

以下是所附财产:

使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
名称空间MyNamespace
{
公共静态类绑定
{
公共静态bool GetVisibilityToEnabled(DependencyObject obj)
{
返回(bool)对象GetValue(VisibilityToEnabledProperty);
}
公共静态无效设置VisibilityToEnabled(DependencyObject对象,布尔值)
{
对象设置值(VisibilityToEnabledProperty,值);
}
公共静态只读从属属性VisibilityToEnabledProperty=
DependencyProperty.RegisterAttached(“VisibilityToEnabled”、typeof(bool)、typeof(Bindings)、new PropertyMetadata(false、OnVisibilityToEnabledChanged));
私有静态void on VisibilityToEnabledChanged(对象发送方,DependencyPropertyChangedEventArgs参数)
{
if(发送方为FrameworkElement)
{
if((bool)args.NewValue)
{
绑定b=新绑定
{
源=元素,
路径=新属性路径(名称(FrameworkElement.IsEnabled)),
Converter=新的BooleanToVisibilityConverter()
};
元素设置绑定(UIElement.VisibilityProperty,b);
}
其他的
{
BindingOperations.ClearBinding(元素,UIElement.VisibilityProperty);
}
}
}
}
}
下面是您将如何使用它:



这个答案没有多大帮助,但我用+1来消除那些我完全不理解为什么有人会给出的负面观点。虽然这个答案没有太大帮助,但其中提到的所有内容都是有效的,而且,所有其他正面标记的答案都使用了提到的内容。这个答案应该得到的最小值是零,而不是否定!这是我最初的想法,但是如何从这个新属性中访问(object param)参数,并将其传递给CanExecute()?这比必要的工作量要大一点,您只需使用触发器就可以了。这很完美-工作起来很有魅力(虽然我使用了带有bool-to-visibility转换器的直接绑定而不是触发器,但想法是一样的)可见性应设置为“折叠”,否则隐藏的菜单项仍会占用空间。是的,这是一个更好的解决方案,尽管根据Roman的建议,可见性应设置为“折叠”。更改可见性是对样式的更改,因此使用样式比直接绑定更有意义ng
Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource booleanToVisibilityConverter}}"