WPF ViewModel的命令CanExecute问题 [英] WPF ViewModel Commands CanExecute issue

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

问题描述

我有我的视图模型有些困难的右键菜单命令。

我实现ICommand接口的视图模型中的每个命令,然后在视图(主窗口)的资源范围内创建一个文本菜单,并使用从MVVMToolkit一个CommandReference访问当前的DataContext(视图模型)命令。

当我调试应用程序,似乎没有被称为除了在创建窗口的命令的CanExecute方法,所以我的上下文的MenuItems没有被启用或禁用,因为我本来期望。

我煮了一个简单的示例(<一个href=\"http://cid-521002f90bfd805d.skydrive.live.com/embedicon.aspx/.Public/WpfCommandTest.zip\">attached这里),这是我的指示实际应用,并总结如下。任何帮助将大大AP preciated!

这是视图模型

 命名空间WpfCommandTest
{
    公共类MainWindowViewModel
    {
        私人列表&LT;串GT;数据=新的List&LT;串GT; {一,二,三};        //这是为了简化这个例子 - 通常我们会链接到
        //域模型的属性
        公开名单&LT;串GT; TESTDATA
        {
            {返回的数据; }
            集合{数据=值; }
        }        //为列表视图绑定属性
        公共字符串的SelectedItem {搞定;组; }        //要执行的命令
        公众的ICommand DisplayValue {搞定;私人集; }        公共MainWindowViewModel()
        {
            DisplayValue =新DisplayValueCommand(本);
        }    }
}

该DisplayValueCommand是这样的:

 公共类DisplayValueCommand:ICommand的
{
    私人MainWindowViewModel视图模型;    公共DisplayValueCommand(MainWindowViewModel视图模型)
    {
        this.viewModel =视图模型;
    }    #区域成员的ICommand    公共BOOL CanExecute(对象参数)
    {
        如果(viewModel.SelectedItem!= NULL)
        {
            返回viewModel.SelectedItem.Length == 3;
        }
        否则返回false;
    }    公共事件的EventHandler CanExecuteChanged;    公共无效执行(对象参数)
    {
        MessageBox.Show(viewModel.SelectedItem);
    }    #endregion
}

最后,该视图在XAML中定义的:

 &LT;窗​​口x:类=WpfCommandTest.Window1
    的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
    的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
    XMLNS:地方=CLR的命名空间:WpfCommandTest
    的xmlns:mvvmtk =CLR的命名空间:MVVMToolkit
    标题=窗口1HEIGHT =300WIDTH =300&GT;    &LT; Window.Resources&GT;        &LT; mvvmtk:CommandReference X:键=showMessageCommandReference命令={结合DisplayValue}/&GT;        &LT;文本菜单X:键=listContextMenu&GT;
            &LT;菜单项标题=显示消息框命令={StaticResource的showMessageCommandReference}/&GT;
        &LT; /文本菜单&GT;    &LT; /Window.Resources>    &LT; Window.DataContext&GT;
        &lt;局部:MainWindowViewModel /&GT;
    &LT; /Window.DataContext>    &LT;网格和GT;
        &LT; ListBox中的ItemsSource ={结合TESTDATA}的ContextMenu ={StaticResource的listContextMenu}
                 的SelectedItem ={结合的SelectedItem}/&GT;
    &LT; /网格和GT;
&LT; /窗GT;


解决方案

要完成威尔的答案,这里有一个标准实施 CanExecuteChanged 活动:

 公共事件的EventHandler CanExecuteChanged
{
    添加{CommandManager.RequerySuggested + =价值; }
    除去{CommandManager.RequerySuggested - =价值; }
}

(从约什 - 史密斯的 RelayCommand 类)

顺便说一句,你应该考虑使用 RelayCommand DelegateCommand :你很快就会感到厌倦创造每一个新的命令类和你的每一个命令的ViewModels ...

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

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.

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!

This is the ViewModel

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);
        }

    }
}

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
}

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>

解决方案

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; }
}

(from Josh Smith's RelayCommand class)

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的命令CanExecute问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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