WPF:MenuItem命令Canexecute未按预期工作

时间:2016-03-07 08:21:06

标签: c# wpf menuitem

好的,所以我的要求非常简单

如果未启用子菜单,我应该禁用父菜单项。

这是代码。

<Grid>
        <Menu>
            <MenuItem Header="File" >
                <MenuItem Header="Open" IsEnabled="{Binding IsEnabled, ElementName=subMenu2}">                    
                    <MenuItem Header="Open_Extended1" x:Name="subMenu2" Command="{Binding SomeCommand}"/>
                </MenuItem>
                <MenuItem Header="Add"/>
            </MenuItem>
        </Menu>
    </Grid>

代码隐藏:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new ViewModel();
    }
}
public class SomeCommand : System.Windows.Input.ICommand
{
    private ViewModel Model;

    public SomeCommand(ViewModel model)
    {
        Model = model;
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public bool CanExecute(object parameter)
    {
        return Model.IsEnabled;
    }

    public void Execute(object parameter)
    {

    }
}
public class ViewModel : System.ComponentModel.INotifyPropertyChanged
{
    private System.Boolean mIsEnabled;

    public System.Boolean IsEnabled
    {
        get
        {
            return mIsEnabled;
        }
        set
        {
            mIsEnabled = value;
            OnPropertyChanged("IsEnabled");
        }
    }

    private SomeCommand mSomeCommand;

    public SomeCommand SomeCommand
    {
        get
        {
            if (mSomeCommand == null)
            {
                mSomeCommand = new SomeCommand(this);
            }
            return mSomeCommand;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

现在问题是Open MenuItem被启用,直到它被暂停,默认情况下它没有被禁用,因为当打开Open Menuitem时会调用subMenuItem命令的CanExecute。

不是在我们点击“文件”时菜单项

那么是否有任何方法可以关注子菜单以便调用CanExecute?

2 个答案:

答案 0 :(得分:2)

您的要求直接针对Menu类的设计。让子子菜单刷新而不显示它将非常棘手和混乱。

但这不是一个大问题,你可以在ViewModel中轻松解决它。引入OpenEnabled属性并绑定到该属性。

答案 1 :(得分:0)

您应该为command再创建一个Open Menu item作为:

public RelayCommand OpenCommand { get; set; }

现在将打开MenuItem绑定到此Command

<MenuItem Header="Open" Command="{Binding Command}">

CanExecute def将是:

 public bool CanExecuteOpen
    {
        get
        {
            //Can also check several menu items command here
            return CanExecuteOpen_Extended1;
        }
    }


 public bool CanExecuteOpen_Extended1
        {
            get
            {
                //Any logic for this command
                return false;
            }
        }
  

理想情况下,如果您要从MenuItems生成ViewModel然后启用通用定义,那会更加简单   Parent menu Item可以轻松编写。但是因为你的菜单项   在XAML中修复我们必须指定哪个子项命令   应检查父母。