ICommand secrets :) Can I creamte my own ICommand replacement ?

JerryM 1,121 Reputation points
2021-05-12T05:49:19.513+00:00

Hello,

I have a small testing code for MVVM in MS VS 2019 v16.9.4 C# .NET5:

https://drive.google.com/file/d/17-GjKU1E22FPJ7szMBoI5Y_H_g6Z-uQh/view?usp=sharing

There are only "class VM" and standardized "RelayCommand : ICommand"... if I push the button "Save" I will see a MessageBox.

So, I tried to create my own ICommand class and I named it ICommandX (lines 24-31, Class.cs file) . If I change the ICommand to ICommandX on lines 39, 41 and 76 the code is not working i.e. the Button Click event is not fired.

Can someone hlep me where is problem ? Is there something like "hidden Microsoft mystery" ? somethong what is not visible for me ?

Jerry

XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
809 questions
{count} votes

Accepted answer
  1. DaisyTian-1203 11,621 Reputation points
    2021-05-20T07:33:29.463+00:00

    The reason using ICommandX doesn't work is because you use Command="{Binding SaveCommand}" in Button. From the document ButtonBase.Command Property, we can get below:

    [System.ComponentModel.Bindable(true)]  
    [System.Windows.Localizability(System.Windows.LocalizationCategory.NeverLocalize)]  
    public System.Windows.Input.ICommand Command { get; set; }  
    

    Command is ICommand not your ICommandX, if you want to use ICommandX, you need to create a DependencyProperty CommandXProperty. If it is not nessary, it is not a good idea to use ICommandX to replace ICommand.


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. JerryM 1,121 Reputation points
    2021-05-15T16:50:57.603+00:00

    Hi, ok once again . The code is below. If I exchange the ICommand and my ICommandX, the program does not work - it is if I run it and put down a text upper into text box and push the button no message box is appeared. If I put back the name ICommand, everything is working ok.

    Here is complette source code:
    https://drive.google.com/file/d/1EITi5SLB1WqVnLL0cSWV4F4F2vLnNBVt/view?usp=sharing

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Input;
    
    
    /*
    #region Assembly System.ObjectModel, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
    // C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\5.0.0\ref\net5.0\System.ObjectModel.dll
    #endregion
    
    #nullable enable
    */
    
    using System.ComponentModel;
    using System.Windows.Markup;
    using System.ComponentModel.DataAnnotations;
    
    namespace WpfApp
    {
    
    
        [TypeConverter("System.Windows.Input.CommandConverter, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null")]
        [ValueSerializer("System.Windows.Input.CommandValueSerializer, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, Custom=null")]
        public interface ICommandX
        {
            event EventHandler? CanExecuteChanged;
            bool CanExecute(object? parameter);
            void Execute(object? parameter);
        }
    
    
    
        public class VM
        {
    
            public String Name { get; set; }
    
            private ICommandX _SaveCommand;
    
            public ICommandX SaveCommand
            {
                get { return _SaveCommand;  }
            }
    
    
            public VM()
            {
                _SaveCommand = new RelayCommand(SaveCommand_Execute, SaveCommand_CanExecute);
            }
    
    
    
            public void SaveCommand_Execute() 
            {
                MessageBox.Show("Save called");
            }
    
            public bool SaveCommand_CanExecute()
            {
    
                if ( string.IsNullOrEmpty(Name))
                {
                    return false;
                }
                else
                {
                    return true;
                }
    
            }
    
    
        }
    
        public class RelayCommand : ICommandX
        {
            private Action methodToxecute;
            private Func<bool> canExecuteEvaluator;
    
            public event EventHandler CanExecuteChanged
            {
                add 
                { 
                    CommandManager.RequerySuggested += value;
                    //MessageBox.Show(value.ToString());
    
                }
                remove { CommandManager.RequerySuggested -= value; }
            }
    
    
            public RelayCommand(Action methodToExecute, Func<bool> canExecuteEvaluator)
            {
                this.methodToxecute = methodToExecute;
                this.canExecuteEvaluator = canExecuteEvaluator;
            }
    
            public RelayCommand(Action methodToExecute) : this(methodToExecute, null)
            {
    
            }
    
            public bool CanExecute(object parameter)
            {
                if ( this.canExecuteEvaluator == null)
                {
                    return true;
                }
                else
                {
                    bool result = this.canExecuteEvaluator.Invoke();
                    return result;
                }
            }
    
            public void Execute(object parameter)
            {
                this.methodToxecute.Invoke();
            }
    
        }
    }
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.