After upgrading Mvvm Light to version 5, what changes do I need to make RelayCommand CanExecute () work?

I upgraded Mvvm Light to version 5 and noticed that RelayCommand stopped working.

The problem is that CanExecute() not being called for verification. It checks only once, for example, when a window is loaded.

Could this be a bug from a recent update, or is there something I need to change in XAML?

Before the update, everything worked correctly. I am working with WPF.

+6
source share
2 answers

See MVVM Light 5 Problem :

WPF is the only XAML framework that uses the CommandManager to automatically raise the CanExecuteChanged event to ICommands. I never liked this approach because of the "magic" part, but this is the "function" of WPF and, of course, I have to support it. There are no questions here.

In V5, I switched to a portable class library for all the latest versions of the XAML framework, including WPF4.5. Unfortunately, there is no CommandManager in PCL, and I must admit that I did not understand that at a glance. So, of course, the auto part doesn't work anymore. Again, so sorry about that.

I do not expect that you will raise CanExecuteChanged everywhere now , and not after using the CommandManager in your application, which is what the WPF Team intended. Therefore, I will try to find a way to restore Using CommandManager in the WPF4.5 toolkit.

Definitely not looking for excuses;), but hope to explain why the problem arises in order to understand this. This will be my No. 1 priority until I find a way to solve this problem in the PCL version. In the meantime, as I mentioned earlier, I think that returning to V4.4.32.7 should fix this. Please let me know if this is not the case.

So, the temporary recommended solution will revert to the previous version . I did it and it worked.

I agree that the CommandManager does the magic. As soon as I had a link exception in the CanExecute , and as a result, I got an endless loop of error messages, such as cards in Windows Solitaire. If I started a new project, I would prefer not to use this "magic", but changing an existing and already deployed project would be rather painful.

+9
source

It looks like you need to call RaiseCanExecuteChanged on the command whenever the corresponding property changes. I think this was previously done by the wpf command manager, but recent changes to the PCL may have made it impossible.

I use MvvmCross, which requires calling a similar method, so in my base view model I have a method that allows me to register a command, so that whenever a property change occurs, I can encode all registered commands and force canececute again. To make your job easier, you can do it this way.

Check out this sample.

Since this seems to be in doubt, here is some code that I tested

 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 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() { // } } } 

No line

 GoCommand.RaiseCanExecuteChanged(); 

the canececute method is never called after the initial call, but with the line that it is called every time the Increment property changes

0
source

Source: https://habr.com/ru/post/976586/


All Articles