WPF ViewModel 命令可以执行问题 [英] WPF ViewModel Commands CanExecute issue

查看:32
本文介绍了WPF ViewModel 命令可以执行问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的视图模型上的上下文菜单命令有些困难.

I'm having some difficulty with Context Menu commands on my View Model.

我正在为 View Model 中的每个命令实现 ICommand 接口,然后在 View (MainWindow) 的资源中创建一个 ContextMenu,并使用 MVVMToolkit 中的 CommandReference 来访问当前的 DataContext (ViewModel) 命令.

I'm implementing the ICommand interface for each command within the View Model, then creating a ContextMenu within the resources of the View (MainWindow), and using a CommandReference from the MVVMToolkit to access the current DataContext (ViewModel) Commands.

当我调试应用程序时,似乎除了在创建窗口时没有调用命令上的 CanExecute 方法,因此我的上下文菜单项没有像我预期的那样被启用或禁用.

When I debug the application, it appears that the CanExecute method on the command is not being called except at the creation of the window, therefore my Context MenuItems are not being enabled or disabled as I would have expected.

我制作了一个简单的示例(附在此处) 这表明我的实际应用并总结如下.任何帮助将不胜感激!

I've cooked up a simple sample (attached here) which is indicative of my actual application and summarised below. Any help would be greatly appreciated!

这是视图模型

namespace WpfCommandTest
{
    public class MainWindowViewModel
    {
        private List<string> data = new List<string>{ "One", "Two", "Three" };

        // This is to simplify this example - normally we would link to
        // Domain Model properties
        public List<string> TestData
        {
            get { return data; }
            set { data = value; }
        }

        // Bound Property for listview
        public string SelectedItem { get; set; }

        // Command to execute
        public ICommand DisplayValue { get; private set; }

        public MainWindowViewModel()
        {
            DisplayValue = new DisplayValueCommand(this);
        }

    }
}

DisplayValueCommand 是这样的:

The DisplayValueCommand is such:

public class DisplayValueCommand : ICommand
{
    private MainWindowViewModel viewModel;

    public DisplayValueCommand(MainWindowViewModel viewModel)
    {
        this.viewModel = viewModel;
    }

    #region ICommand Members

    public bool CanExecute(object parameter)
    {
        if (viewModel.SelectedItem != null)
        {
            return viewModel.SelectedItem.Length == 3;
        }
        else return false;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        MessageBox.Show(viewModel.SelectedItem);
    }

    #endregion
}

最后,视图在 Xaml 中定义:

And finally, the view is defined in Xaml:

<Window x:Class="WpfCommandTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfCommandTest"
    xmlns:mvvmtk="clr-namespace:MVVMToolkit"
    Title="Window1" Height="300" Width="300">

    <Window.Resources>

        <mvvmtk:CommandReference x:Key="showMessageCommandReference" Command="{Binding DisplayValue}" />

        <ContextMenu x:Key="listContextMenu">
            <MenuItem Header="Show MessageBox" Command="{StaticResource showMessageCommandReference}"/>
        </ContextMenu>

    </Window.Resources>

    <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>

    <Grid>
        <ListBox ItemsSource="{Binding TestData}" ContextMenu="{StaticResource listContextMenu}" 
                 SelectedItem="{Binding SelectedItem}" />
    </Grid>
</Window>

推荐答案

为了完成 Will 的回答,这里是 CanExecuteChanged 事件的标准"实现:

To complete Will's answer, here's a "standard" implementation of the CanExecuteChanged event :

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

(来自 Josh Smith 的 RelayCommand 类)

(from Josh Smith's RelayCommand class)

顺便说一句,您可能应该考虑使用 RelayCommandDelegateCommand :您很快就会厌倦为 ViewModel 的每个命令创建新的命令类...

By the way, you should probably consider using RelayCommand or DelegateCommand : you'll quickly get tired of creating new command classes for each and every command of you ViewModels...

这篇关于WPF ViewModel 命令可以执行问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆