【问题标题】:After updating Mvvm Light to Version 5, what changes do I need to make RelayCommand CanExecute() work?将 Mvvm Light 更新到版本 5 后,我需要进行哪些更改才能使 RelayCommand CanExecute() 工作?
【发布时间】:2014-10-10 19:31:15
【问题描述】:

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

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

这可能是最近更新中的错误,还是我需要在 XAML 中进行更改?

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

【问题讨论】:

  • 同样的问题,应该已经找到你的帖子了。我不得不降级回以前的版本。

标签: c# wpf mvvm-light


【解决方案1】:

看到这个MVVM Light 5 issue

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

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

我不希望你现在到处提出 CanExecuteChanged,不是 在您的应用程序中使用 CommandManager 之后, WPF 团队打算。所以我会尝试找到一种方法来恢复 WPF4.5版本工具包中CommandManager的使用。

绝对不是在找借口;)但希望能解释为什么 出现的问题有助于理解这一点。这将是我的首要任务 第一,直到我在 PCL 版本中找到解决这个问题的方法。与此同时,就像我之前提到的,我认为回到 V4.4.32.7 应该解决这个问题。如果没有,请告诉我。

所以临时推荐的解决方案是恢复到以前的版本。我做到了,它奏效了。

我同意 CommandManager 正在做“魔术”。一旦我在CanExecute 条件中出现空引用异常,因此我获得了无休止的错误消息循环,例如 Windows Solitaire 中的卡片。如果我开始一个新项目,我宁愿不使用这种“魔法”,但更改现有和已经部署的项目会非常痛苦。

【讨论】:

  • 在 5.0.2 版本中修复。
  • 要使用 v5.0.2 中的修复,请务必从 GalaSoft.MvvmLight.Command 更改命名空间;到 GalaSoft.MvvmLight.CommandWpf;
【解决方案2】:

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

我使用需要调用类似方法的 MvvmCross,因此在我的基本视图模型中,我有一个方法允许我注册一个命令,以便每当发生属性更改时,我都可以循环所有注册的命令并强制可以执行被调用再次。为了让事情变得更容易,你可以这样做。

Check out this sample

由于这似乎受到怀疑,这是我测试过的一些代码

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 属性更改时都会调用它

【讨论】:

  • 也许如果你真的尝试过我建议的,你会发现我实际上是正确的。所以我实际上认为这是一个非常有用的答案。我添加了一些我已经测试过的额外示例代码,它可以工作。
  • 想象你有一个项目,你必须经历数百个这样的案例并再次测试一切。你愿意吗?
  • 我同意这对于一个已经有很多命令的大型项目来说是不可取的,但是对于任何刚开始使用 MVVMLight 的人来说,它可以节省他们的时间。
猜你喜欢
  • 1970-01-01
  • 2021-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-26
  • 2021-01-21
  • 1970-01-01
  • 2015-03-25
相关资源
最近更新 更多