Edited ViewModelBase.NotifyPropertyChanged handlers, for interested parties

Aug 16, 2011 at 8:27 PM

Hi all -

In case anyone is interested, I've found this bit of code useful.  You may as well, especially if you create ViewModels in threads other than the main GUI thread as I sometimes do in my apps.  This change reduces or sometimes eliminates the need to either pass a Dispatcher around or to use the IViewStatusAwareInjectionAware interface.

In ViewModelBase.cs, replace the INotifyPropertyChanged region with the code pasted below.  When raising the PropertyChanged event, a View Model using this code will raise the event using the Invoke mechanism if needed, on any object derived from the DispatcherObject class.  DispatcherObject is the parent class for all (I think) classes within WPF that have bindable attributes.  So, use and enjoy.  And thanks again, Sacha, for all your terrific work on Cinch!

--Dave

       #region INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Notify using pre-made PropertyChangedEventArgs
        /// </summary>
        /// <param name="args"></param>
        protected void NotifyPropertyChanged(PropertyChangedEventArgs args)
        {
            var handlers = PropertyChanged;
            if (handlers == null) return;
            foreach (PropertyChangedEventHandler handler in handlers.GetInvocationList())
            {
                if (handler.Target is DispatcherObject)
                    ((DispatcherObject)handler.Target).Dispatcher.InvokeIfRequired(() => handler(this, args));
                else
                    handler(this, args);
            }
        }

        /// <summary>
        /// Notify using String property name
        /// </summary>
        protected void NotifyPropertyChanged(String propertyName)
        {
            this.VerifyPropertyName(propertyName);
            var handlers = PropertyChanged;
            if (handlers == null) return;
            foreach (PropertyChangedEventHandler handler in handlers.GetInvocationList())
            {
                if (handler.Target is DispatcherObject)
                    ((DispatcherObject)handler.Target).Dispatcher.InvokeIfRequired(() => handler(this, new PropertyChangedEventArgs(propertyName)));
                else
                    handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion

Aug 21, 2011 at 6:06 PM

Yep sensible enough, and quite similar to something I do in the DispatcherNotifiedObservableCollection<T> class in Cinch already