OneComputeWpfClient\Support\NotifyPropertyChangedBase.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using System.Threading;

namespace OneComputeWpfClient.Support
{
    /// <summary>
    /// Base class for raising property changed notifications.
    /// </summary>
    /// <seealso cref="System.ComponentModel.INotifyPropertyChanged" />
    public abstract class NotifyPropertyChangedBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private static SynchronizationContext _synchronizationContext;

        static NotifyPropertyChangedBase()
        {
            _synchronizationContext = SynchronizationContext.Current;
        }

        protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
        {
            if (_synchronizationContext != null)
            {
                _synchronizationContext.Post(
                    state => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)), null);
            }
            else
            {
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        protected virtual void RaisePropertyChanged<T>(Expression<Func<T>> selectorExpression)
        {
            CheckForNullSynchronizationContext();

            if (selectorExpression == null)
                throw new ArgumentNullException(nameof(selectorExpression));

            if (!(selectorExpression.Body is MemberExpression memberExpression))
                throw new ArgumentException("The body must be a member expression.");

            RaisePropertyChanged(memberExpression.Member.Name);
        }

        protected bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            var propertySet = false;

            if (!Equals(storage, value))
            {
                storage = value;
                RaisePropertyChanged(propertyName);
                propertySet = true;
            }

            return propertySet;
        }

        protected bool SetField<T>(ref T field, T value, Expression<Func<T>> selectorExpression)
        {
            CheckForNullSynchronizationContext();

            var fieldSet = false;

            if (!EqualityComparer<T>.Default.Equals(field, value))
            {
                field = value;
                RaisePropertyChanged(selectorExpression);
                fieldSet = true;
            }

            return fieldSet;
        }

        private static void CheckForNullSynchronizationContext()
        {
            if (_synchronizationContext == null)
            {
                _synchronizationContext = SynchronizationContext.Current;
            }
        }
    }
}
  • Edit this page
In this article
Back to top Copyright © DNV AS. All rights reserved.