WPF MVVM Command CanExecute, reevaluates only at focus change
<p>Refactoring an <strong>MVVM</strong> project in <strong>WPF</strong>, I'm trying to get rid of what seems a common problem between MVVM pattern users.</p>

<p>I have view, who's <strong>DataContext</strong> is <strong>MyViewModel</strong>. Here is a button, bound with a Command that implements both Execute and CanExecute.</p>

<p>XAML:</p>

<pre><code>&lt;Button Command="{Binding ConnectCommand}"/&gt;
</code></pre>

<p><strong>MyViewModel</strong> exposes <strong>ConnectCommand</strong>:</p>

<pre><code>public ICommand ConnectCommand
    {
        get { return new DelegateCommand(() =&gt; Connect(), () =&gt; IsConnectEnabled); }
    }
</code></pre>

<p><em>(at the end the definition of DelegateCommand I'm using)</em></p>

<p><strong>MyViewModel</strong> also exposes the property <strong>IsConnectEnabled</strong>, used in the CanExecute part of the Command:</p>

<pre><code>public bool IsConnectEnabled
        {
            get
            {
                return (isDisconnected &amp;&amp; null!=selectedDevice &amp;&amp; 0&lt;selectedDevice.Length);
            }
        }
</code></pre>

<p><strong>MyViewModel</strong> class implements the <strong>INotifyPropertyChanged</strong> interface</p>

<pre><code>public class MyViewModel : INotifyPropertyChanged
{
    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion

    #region rest of the class        
}
</code></pre>

<p>The <strong>CanExecute</strong> part of the command is only evaluated on a change of focus in the application (ie, whatever click I do). I know that the <strong>UpdateSourceTrigger</strong> is by default set to <strong>PropertyChanged</strong>, therefore my current solution, is to manually raise a <strong>PropertyChanged</strong> event in a few places in the code. But I want to do better and have this activity done automatically whenever the value of <strong>IsConnectEnabled</strong> changes.</p>

<p>Does the WPF and the MVVM pattern offer a solution for this issue?</p>

<p>For completeness, follows the complete <strong>ICommand</strong> implementation I'm using, <strong>DelegateCommand</strong>:</p>

<pre><code>    /// &lt;summary&gt;
    ///     This class allows delegating the commanding logic to methods passed as parameters,
    ///     and enables a View to bind commands to objects that are not part of the element tree.
    /// &lt;/summary&gt;
    public class DelegateCommand : ICommand
    {
        /// &lt;summary&gt;
        ///     Constructor
        /// &lt;/summary&gt;
        public DelegateCommand(Action executeMethod)
            : this(executeMethod, null, false)
        {
        }

        /// &lt;summary&gt;
        ///     Constructor
        /// &lt;/summary&gt;
        public DelegateCommand(Action executeMethod, Func&lt;bool&gt; canExecuteMethod)
            : this(executeMethod, canExecuteMethod, false)
        {
        }

        /// &lt;summary&gt;
        ///     Constructor
        /// &lt;/summary&gt;
        public DelegateCommand(Action executeMethod, Func&lt;bool&gt; canExecuteMethod, bool isAutomaticRequeryDisabled)
        {
            if (executeMethod == null)
            {
                throw new ArgumentNullException("executeMethod");
            }

            _executeMethod = executeMethod;
            _canExecuteMethod = canExecuteMethod;
            _isAutomaticRequeryDisabled = isAutomaticRequeryDisabled;
        }

        #region Public Methods

        /// &lt;summary&gt;
        ///     Method to determine if the command can be executed
        /// &lt;/summary&gt;
        public bool CanExecute()
        {
            if (_canExecuteMethod != null)
            {
                return _canExecuteMethod();
            }
            return true;
        }

        /// &lt;summary&gt;
        ///     Execution of the command
        /// &lt;/summary&gt;
        public void Execute()
        {
            if (_executeMethod != null)
            {
                _executeMethod();
            }
        }

        /// &lt;summary&gt;
        ///     Property to enable or disable CommandManager's automatic requery on this command
        /// &lt;/summary&gt;
        public bool IsAutomaticRequeryDisabled
        {
            get
            {
                return _isAutomaticRequeryDisabled;
            }
            set
            {
                if (_isAutomaticRequeryDisabled != value)
                {
                    if (value)
                    {
                        CommandManagerHelper.RemoveHandlersFromRequerySuggested(_canExecuteChangedHandlers);
                    }
                    else
                    {
                        CommandManagerHelper.AddHandlersToRequerySuggested(_canExecuteChangedHandlers);
                    }
                    _isAutomaticRequeryDisabled = value;
                }
            }
        }

        /// &lt;summary&gt;
        ///     Raises the CanExecuteChaged event
        /// &lt;/summary&gt;
        public void RaiseCanExecuteChanged()
        {
            OnCanExecuteChanged();
        }

        /// &lt;summary&gt;
        ///     Protected virtual method to raise CanExecuteChanged event
        /// &lt;/summary&gt;
        protected virtual void OnCanExecuteChanged()
        {
            CommandManagerHelper.CallWeakReferenceHandlers(_canExecuteChangedHandlers);
        }

        #endregion

        #region ICommand Members

        /// &lt;summary&gt;
        ///     ICommand.CanExecuteChanged implementation
        /// &lt;/summary&gt;
        public event EventHandler CanExecuteChanged
        {
            add
            {
                if (!_isAutomaticRequeryDisabled)
                {
                    CommandManager.RequerySuggested += value;
                }
                CommandManagerHelper.AddWeakReferenceHandler(ref _canExecuteChangedHandlers, value, 2);
            }
            remove
            {
                if (!_isAutomaticRequeryDisabled)
                {
                    CommandManager.RequerySuggested -= value;
                }
                CommandManagerHelper.RemoveWeakReferenceHandler(_canExecuteChangedHandlers, value);
            }
        }

        bool ICommand.CanExecute(object parameter)
        {
            return CanExecute();
        }

        void ICommand.Execute(object parameter)
        {
            Execute();
        }

        #endregion

        #region Data

        private readonly Action _executeMethod = null;
        private readonly Func&lt;bool&gt; _canExecuteMethod = null;
        private bool _isAutomaticRequeryDisabled = false;
        private List&lt;WeakReference&gt; _canExecuteChangedHandlers;

        #endregion
    }

    /// &lt;summary&gt;
    ///     This class allows delegating the commanding logic to methods passed as parameters,
    ///     and enables a View to bind commands to objects that are not part of the element tree.
    /// &lt;/summary&gt;
    /// &lt;typeparam name="T"&gt;Type of the parameter passed to the delegates&lt;/typeparam&gt;
    public class DelegateCommand&lt;T&gt; : ICommand
    {
        #region Constructors

        /// &lt;summary&gt;
        ///     Constructor
        /// &lt;/summary&gt;
        public DelegateCommand(Action&lt;T&gt; executeMethod)
            : this(executeMethod, null, false)
        {
        }

        /// &lt;summary&gt;
        ///     Constructor
        /// &lt;/summary&gt;
        public DelegateCommand(Action&lt;T&gt; executeMethod, Func&lt;T, bool&gt; canExecuteMethod)
            : this(executeMethod, canExecuteMethod, false)
        {
        }

        /// &lt;summary&gt;
        ///     Constructor
        /// &lt;/summary&gt;
        public DelegateCommand(Action&lt;T&gt; executeMethod, Func&lt;T, bool&gt; canExecuteMethod, bool isAutomaticRequeryDisabled)
        {
            if (executeMethod == null)
            {
                throw new ArgumentNullException("executeMethod");
            }

            _executeMethod = executeMethod;
            _canExecuteMethod = canExecuteMethod;
            _isAutomaticRequeryDisabled = isAutomaticRequeryDisabled;
        }

        #endregion

        #region Public Methods

        /// &lt;summary&gt;
        ///     Method to determine if the command can be executed
        /// &lt;/summary&gt;
        public bool CanExecute(T parameter)
        {
            if (_canExecuteMethod != null)
            {
                return _canExecuteMethod(parameter);
            }
            return true;
        }

        /// &lt;summary&gt;
        ///     Execution of the command
        /// &lt;/summary&gt;
        public void Execute(T parameter)
        {
            if (_executeMethod != null)
            {
                _executeMethod(parameter);
            }
        }

        /// &lt;summary&gt;
        ///     Raises the CanExecuteChaged event
        /// &lt;/summary&gt;
        public void RaiseCanExecuteChanged()
        {
            OnCanExecuteChanged();
        }

        /// &lt;summary&gt;
        ///     Protected virtual method to raise CanExecuteChanged event
        /// &lt;/summary&gt;
        protected virtual void OnCanExecuteChanged()
        {
            CommandManagerHelper.CallWeakReferenceHandlers(_canExecuteChangedHandlers);
        }

        /// &lt;summary&gt;
        ///     Property to enable or disable CommandManager's automatic requery on this command
        /// &lt;/summary&gt;
        public bool IsAutomaticRequeryDisabled
        {
            get
            {
                return _isAutomaticRequeryDisabled;
            }
            set
            {
                if (_isAutomaticRequeryDisabled != value)
                {
                    if (value)
                    {
                        CommandManagerHelper.RemoveHandlersFromRequerySuggested(_canExecuteChangedHandlers);
                    }
                    else
                    {
                        CommandManagerHelper.AddHandlersToRequerySuggested(_canExecuteChangedHandlers);
                    }
                    _isAutomaticRequeryDisabled = value;
                }
            }
        }

        #endregion

        #region ICommand Members

        /// &lt;summary&gt;
        ///     ICommand.CanExecuteChanged implementation
        /// &lt;/summary&gt;
        public event EventHandler CanExecuteChanged
        {
            add
            {
                if (!_isAutomaticRequeryDisabled)
                {
                    CommandManager.RequerySuggested += value;
                }
                CommandManagerHelper.AddWeakReferenceHandler(ref _canExecuteChangedHandlers, value, 2);
            }
            remove
            {
                if (!_isAutomaticRequeryDisabled)
                {
                    CommandManager.RequerySuggested -= value;
                }
                CommandManagerHelper.RemoveWeakReferenceHandler(_canExecuteChangedHandlers, value);
            }
        }

        bool ICommand.CanExecute(object parameter)
        {
            // if T is of value type and the parameter is not
            // set yet, then return false if CanExecute delegate
            // exists, else return true
            if (parameter == null &amp;&amp;
                typeof(T).IsValueType)
            {
                return (_canExecuteMethod == null);
            }
            return CanExecute((T)parameter);
        }

        void ICommand.Execute(object parameter)
        {
            Execute((T)parameter);
        }

        #endregion

        #region Data

        private readonly Action&lt;T&gt; _executeMethod = null;
        private readonly Func&lt;T, bool&gt; _canExecuteMethod = null;
        private bool _isAutomaticRequeryDisabled = false;
        private List&lt;WeakReference&gt; _canExecuteChangedHandlers;

        #endregion
    }

    /// &lt;summary&gt;
    ///     This class contains methods for the CommandManager that help avoid memory leaks by
    ///     using weak references.
    /// &lt;/summary&gt;
    internal class CommandManagerHelper
    {
        internal static void CallWeakReferenceHandlers(List&lt;WeakReference&gt; handlers)
        {
            if (handlers != null)
            {
                // Take a snapshot of the handlers before we call out to them since the handlers
                // could cause the array to me modified while we are reading it.

                EventHandler[] callees = new EventHandler[handlers.Count];
                int count = 0;

                for (int i = handlers.Count - 1; i &gt;= 0; i--)
                {
                    WeakReference reference = handlers[i];
                    EventHandler handler = reference.Target as EventHandler;
                    if (handler == null)
                    {
                        // Clean up old handlers that have been collected
                        handlers.RemoveAt(i);
                    }
                    else
                    {
                        callees[count] = handler;
                        count++;
                    }
                }

                // Call the handlers that we snapshotted
                for (int i = 0; i &lt; count; i++)
                {
                    EventHandler handler = callees[i];
                    handler(null, EventArgs.Empty);
                }
            }
        }

        internal static void AddHandlersToRequerySuggested(List&lt;WeakReference&gt; handlers)
        {
            if (handlers != null)
            {
                foreach (WeakReference handlerRef in handlers)
                {
                    EventHandler handler = handlerRef.Target as EventHandler;
                    if (handler != null)
                    {
                        CommandManager.RequerySuggested += handler;
                    }
                }
            }
        }

        internal static void RemoveHandlersFromRequerySuggested(List&lt;WeakReference&gt; handlers)
        {
            if (handlers != null)
            {
                foreach (WeakReference handlerRef in handlers)
                {
                    EventHandler handler = handlerRef.Target as EventHandler;
                    if (handler != null)
                    {
                        CommandManager.RequerySuggested -= handler;
                    }
                }
            }
        }

        internal static void AddWeakReferenceHandler(ref List&lt;WeakReference&gt; handlers, EventHandler handler)
        {
            AddWeakReferenceHandler(ref handlers, handler, -1);
        }

        internal static void AddWeakReferenceHandler(ref List&lt;WeakReference&gt; handlers, EventHandler handler, int defaultListSize)
        {
            if (handlers == null)
            {
                handlers = (defaultListSize &gt; 0 ? new List&lt;WeakReference&gt;(defaultListSize) : new List&lt;WeakReference&gt;());
            }

            handlers.Add(new WeakReference(handler));
        }

        internal static void RemoveWeakReferenceHandler(List&lt;WeakReference&gt; handlers, EventHandler handler)
        {
            if (handlers != null)
            {
                for (int i = handlers.Count - 1; i &gt;= 0; i--)
                {
                    WeakReference reference = handlers[i];
                    EventHandler existingHandler = reference.Target as EventHandler;
                    if ((existingHandler == null) || (existingHandler == handler))
                    {
                        // Clean up old handlers that have been collected
                        // in addition to the handler that is to be removed.
                        handlers.RemoveAt(i);
                    }
                }
            }
        }
    }
}
</code></pre>