Wpf MenuItem可见性绑定到RelayCommand可以使用参数执行

Wpf MenuItem可见性绑定到RelayCommand可以使用参数执行,wpf,contextmenu,relaycommand,Wpf,Contextmenu,Relaycommand,我正在WPF MVVM应用程序中使用Josh Smith RelayCommand类在ViewModel中创建命令: public bool CanRemoveAll(object param) { GoldTreeNodeViewModel gtn = param as GoldTreeNodeViewModel; return (gtn != null && gtn.Children != null && gtn

我正在WPF MVVM应用程序中使用Josh Smith RelayCommand类在ViewModel中创建命令:

    public bool CanRemoveAll(object param)
    {
        GoldTreeNodeViewModel gtn = param as GoldTreeNodeViewModel;
        return (gtn != null && gtn.Children != null && gtn.Children.Count > 0);
    }
例如:

ICommand RemoveAllCommand = new RelayCommand<object>(OnRemoveAll, CanRemoveAll);
从RelayCommand类:

public event EventHandler CanExecuteChanged
    {
        add
        {
            if (_canExecute != null)
                CommandManager.RequerySuggested += value;
        }
        remove
        {
            if (_canExecute != null)
                CommandManager.RequerySuggested -= value;
        }
    }

    [DebuggerStepThrough]
    public Boolean CanExecute(Object parameter)
    {
        return _canExecute == null ? true : _canExecute((T) parameter);
    }
非常感谢您的帮助,


 <ContextMenu x:Key="MyContextMenu" DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}">
        <MenuItem Header="Remove All" Command="{Binding Path=DataContext.RemoveAllCommand,
                              RelativeSource={RelativeSource AncestorType={x:Type TreeView}}}" CommandParameter="{Binding Path=.Header}" 
                  Visibility="{Binding DataContext.RemoveVisibility,RelativeSource={RelativeSource AncestorType={x:Type TreeView}}}"
                  />

private Visibility _removeVisibility;

    public Visibility RemoveVisibility
    {
        get { return _removeVisibility; }
        set { _removeVisibility = value; Notify("RemoveVisibility"); }
    }

    public bool CanRemoveAll(object param)
    {
        GoldTreeNodeViewModel gtn = param as GoldTreeNodeViewModel;
        bool result= (gtn != null && gtn.Children != null && gtn.Children.Count > 0);
        if (result)
            RemoveVisibility = Visibility.Visible;
        else
            RemoveVisibility = Visibility.Collapsed;
        return result;
    }
私人能见度(u removevision);; 公众能见度 { 获取{return\u removeVisibility;} 设置{u removeVisibility=value;Notify(“removeVisibility”);} } 公共布尔CanRemoveAll(对象参数) { GoldTreeNodeViewModel gtn=参数为GoldTreeNodeViewModel; bool结果=(gtn!=null&>n.Children!=null&>n.Children.Count>0); 如果(结果) RemoveVisibility=可见性。可见; 其他的 RemoveVisibility=可见性。已折叠; 返回结果; }
我认为您绑定的DataContext对应于您的ViewModel。我希望这会有所帮助。


私人能见度(u removevision);;
公众能见度
{
获取{return\u removeVisibility;}
设置{u removeVisibility=value;Notify(“removeVisibility”);}
}
公共布尔CanRemoveAll(对象参数)
{
GoldTreeNodeViewModel gtn=参数为GoldTreeNodeViewModel;
bool结果=(gtn!=null&>n.Children!=null&>n.Children.Count>0);
如果(结果)
RemoveVisibility=可见性。可见;
其他的
RemoveVisibility=可见性。已折叠;
返回结果;
}

我认为您绑定的DataContext对应于您的ViewModel。我希望这会有所帮助。

您能在VM中显示CanRemoveAll的代码,以及您从何处提升CanExecuteChange的代码。刚刚将该信息添加到问题中。。另外,我没有在任何地方明确提出CanExecuteChanged,我认为据我所知,
RelayCommand
和WPF内部会解决这个问题。你能不能在VM中显示CanRemoveAll的代码,以及从哪里提出CanExecuteChanged。只是在问题中添加了这个信息。。此外,我并没有在任何地方明确地提出
CanExecuteChanged
,我认为
RelayCommand
和WPF内部就我所知解决了这个问题。哦,这很有意义,尽管我可能需要使用bool-to-Visibility转换器,但这是次要的。让我试试,谢谢你的建议。是的,你可以这样做,并创建转换器将bool转换为Visibility。虽然我不确定是否要在VM中创建一个Visibility类型属性,这听起来更像是与视图相关的属性,但我可以创建一个
public bool IsRemoveAllVisible
属性……这很有效,但我想知道是否有一种替代方法可以做到这一点,而不必在VM中为每个MenuItem创建额外的可见性属性…我创建该可见性属性只是为了让您了解如何做到这一点,否则我将不得不做更多的工作,如创建转换器等,以及使用单个属性处理所有MenuItemhmmm为此,您可以创建字符串属性(为其指定命令参数),并将此属性绑定到所有MenuItems Visisbility属性,创建转换器,并在此过程标头中将“Add”等值作为转换器参数,然后在转换器中比较,如果值和转换器参数相同,则设置Visibility Visible或Collapsed。这也是一个我不确定的想法。哦,这很有意义,虽然我可能需要使用我的bool-to-Visibility转换器,但这是次要的。让我试试,谢谢你的建议。是的,你可以这样做,并创建转换器将bool转换为Visibility。虽然我不确定是否要在VM中创建一个Visibility类型属性,这听起来更像是与视图相关的属性,但我可以创建一个
public bool IsRemoveAllVisible
属性……这很有效,但我想知道是否有一种替代方法可以做到这一点,而不必在VM中为每个MenuItem创建额外的可见性属性…我创建该可见性属性只是为了让您了解如何做到这一点,否则我将不得不做更多的工作,如创建转换器等,以及使用单个属性处理所有MenuItemhmmm为此,您可以创建字符串属性(为其指定命令参数),并将此属性绑定到所有MenuItems Visisbility属性,创建转换器,并在此过程标头中将“Add”等值作为转换器参数,然后在转换器中比较,如果值和转换器参数相同,则设置Visibility Visible或Collapsed。这也只是一个想法,我不确定。
 <ContextMenu x:Key="MyContextMenu" DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}">
        <MenuItem Header="Remove All" Command="{Binding Path=DataContext.RemoveAllCommand,
                              RelativeSource={RelativeSource AncestorType={x:Type TreeView}}}" CommandParameter="{Binding Path=.Header}" 
                  Visibility="{Binding DataContext.RemoveVisibility,RelativeSource={RelativeSource AncestorType={x:Type TreeView}}}"
                  />

private Visibility _removeVisibility;

    public Visibility RemoveVisibility
    {
        get { return _removeVisibility; }
        set { _removeVisibility = value; Notify("RemoveVisibility"); }
    }

    public bool CanRemoveAll(object param)
    {
        GoldTreeNodeViewModel gtn = param as GoldTreeNodeViewModel;
        bool result= (gtn != null && gtn.Children != null && gtn.Children.Count > 0);
        if (result)
            RemoveVisibility = Visibility.Visible;
        else
            RemoveVisibility = Visibility.Collapsed;
        return result;
    }