The Most Easy to Use ViewModeBase

This is something I wrote for an application I’m developing. This is an implementation of INotifyPropertyChanged that requires no backing fields, just call Set(value) or Get(). Internally it uses a dictionary to store the state and even reuses ChangedEventArgs

The source code can be found at:

https://github.com/ebalynn/StatefulViewModel/

Here is the extract from the ViewModel class that does all the heavy lifting:

using System;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading;

namespace Balynn.xxx
{
    public abstract class ViewModel : INotifyPropertyChanged
    {
        private readonly Lazy<ConcurrentDictionary<string, object>> _propertyRefValues = 
            new Lazy<ConcurrentDictionary<string, object>>(LazyThreadSafetyMode.ExecutionAndPublication);

        private readonly Lazy<ConcurrentDictionary<string, PropertyChangedEventArgs>> _propertyChangedEventArgs =
            new Lazy<ConcurrentDictionary<string, PropertyChangedEventArgs>>();


        public event PropertyChangedEventHandler PropertyChanged;


        protected virtual T Get<T>(T defaultValue = default, [CallerMemberName] string propertyName = null)
        {
            if (_propertyRefValues.Value.ContainsKey(propertyName))
            {
                return (T) _propertyRefValues.Value[propertyName];
            }

            return defaultValue;
        }

        protected virtual bool Set<T>(T value, [CallerMemberName] string propertyName = null)
        {
            var existing = Get(default(T), propertyName);

            if (object.Equals(existing, value) == false)
            {
                _propertyRefValues.Value[propertyName] = value;

                RaisePropertyChanged(propertyName);

                return true;
            }

            return false;
        }

        protected virtual void RaisePropertyChanged([CallerMemberName] string propertyName = null)
        {
            var propertyArgs = _propertyChangedEventArgs.Value
                .GetOrAdd(propertyName, new PropertyChangedEventArgs(propertyName));

            PropertyChanged?.Invoke(this, propertyArgs);
        } 
    }
}
Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at WordPress.com.

Up ↑

%d bloggers like this: