繁体   English   中英

将Mvvm Light更新为版本5后,我需要做哪些更改才能使RelayCommand CanExecute()工作?

[英]After updating Mvvm Light to Version 5, what changes do I need to make RelayCommand CanExecute() work?

我将Mvvm Light更新为版本5并注意到RelayCommand停止工作。

问题似乎是没有调用CanExecute()进行验证。 它只验证一次,就像加载窗口时一样。

这可能是最近更新中的错误还是我需要在XAML中更改某些内容?

在更新之前一切正常。 我正在使用WPF。

看到这个MVVM Light 5问题

WPF是唯一一个使用CommandManager在ICommands上自动引发CanExecuteChanged事件的XAML框架。 我从不喜欢这种方法,因为“神奇”部分,但这是WPF的“功能”,当然我必须支持它。 这里没问题。

在V5中,我转移到了所有最新版本的XAML框架的可移植类库,包括WPF4.5。 不幸的是,PCL中没有CommandManager,我不得不承认我没有意识到这一点。 所以当然现在自动部件不再起作用了。 再一次,很抱歉。

我不希望你现在到处都提出CanExecuteChanged ,而不是在你的应用程序中使用CommandManager之后,这是WPF团队的意图。 因此,我将尝试在WPF4.5版本的工具包中找到恢复CommandManager用法的方法。

绝对不寻找借口;)但希望解释为什么问题出现有助于理解这一点。 在我找到一种方法在PCL版本中解决这个问题之前,这将是我的第一号优先事项。 与此同时,正如我之前提到的,我认为回到V4.4.32.7应该可以解决这个问题。 如果没有,请告诉我。

因此,临时建议的解决方案是恢复到以前的版本 我做到了它并且有效。

我同意CommandManager正在做“魔术”。 一旦我在CanExecute条件中CanExecute引用异常,结果我已经获得了像Windows Solitaire中的卡一样的错误消息的CanExecute循环。 如果我开始一个新项目,我宁愿不使用这个“魔术”,但改变现有的已经部署的项目将是非常痛苦的。

看起来每当相关属性发生变化时,您必须在命令上调用RaiseCanExecuteChanged。 我认为这是以前由wpf命令管理器完成的,但最近的PCL更改可能使得它不受支持。

我使用MvvmCross,它需要一个类似的方法来调用,所以在我的基本视图模型中,我有一个允许我注册命令的方法,这样每当属性发生变化时,我都可以循环所有已注册的命令并强制再次调用canexecute。 为了方便起见,你可以这样做。

看看这个样本

由于这似乎有所怀疑,这里有一些我测试过的代码

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System;

namespace TestingApp.ViewModel
{
    /// <summary>
    /// This class contains properties that the main View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm
    /// </para>
    /// </summary>
    public class MainViewModel : ViewModelBase
    {
        private Int32 _increment = 0;

        public Int32 Increment
        {
            get { return _increment; }
            set
            {
                _increment = value;
                RaisePropertyChanged("Increment");
                GoCommand.RaiseCanExecuteChanged();
            }
        }

        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            ////if (IsInDesignMode)
            ////{
            ////    // Code runs in Blend --> create design time data.
            ////}
            ////else
            ////{
            ////    // Code runs "for real"
            ////}
        }

        private RelayCommand _incrementCommand;

        public RelayCommand IncrementCommand
        {
            get
            {
                if (_incrementCommand == null)
                {
                    _incrementCommand = new RelayCommand(IncrementCommand_Execute);
                }
                return _incrementCommand;
            }
        }

        private void IncrementCommand_Execute()
        {
            Increment++;
        }

        private RelayCommand _goCommand;

        public RelayCommand GoCommand
        {
            get
            {
                if (_goCommand == null)
                {
                    _goCommand = new RelayCommand(GoCommand_Execute, GoCommand_CanExecute);
                }
                return _goCommand;
            }
        }

        private bool GoCommand_CanExecute()
        {
            return Increment > 5;
        }

        private void GoCommand_Execute()
        {
            //
        }
    }
}

没有线

GoCommand.RaiseCanExecuteChanged();

在初始调用之后永远不会调用canexecute方法,但是每次Increment属性更改时都会调用它

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM