Advertisement
wjcustode

NotifyOnPropertyChanged Implementation

Jul 23rd, 2015
289
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.82 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Diagnostics;
  5. using System.Runtime.CompilerServices;
  6. using System.Threading.Tasks;
  7. using System.Windows.Threading;
  8.  
  9. namespace NotifyOnPropertyChangedExample
  10. {
  11.     public class PretendViewModel : NotifyOnPropertyChanged
  12.     {
  13.         public string Name
  14.         {
  15.             get
  16.             {
  17.                 return GetField<string>();
  18.             }
  19.             set
  20.             {
  21.                 SetField(value);
  22.             }
  23.         }
  24.  
  25.         public void SomeMethod()
  26.         {
  27.             Task.Factory.StartNew(() =>
  28.                 {
  29.                     Name = "Status update!";
  30.                 });
  31.         }
  32.     }
  33.  
  34.     public class NotifyOnPropertyChanged : INotifyPropertyChanged
  35.     {
  36.         #region Private Fields
  37.  
  38.         private IDictionary<string, PropertyChangedEventArgs> _args;
  39.  
  40.         private IDictionary<string, object> _fields;
  41.  
  42.         #endregion
  43.  
  44.         #region Protected Methods
  45.  
  46.         protected T GetField<T>([CallerMemberName]string name = "")
  47.         {
  48.             return GetField(default(T), name);
  49.         }
  50.  
  51.         protected T GetField<T>(T defaultValue, [CallerMemberName]string name = "")
  52.         {
  53.             var output = defaultValue;
  54.  
  55.             if (_fields != null && _fields.ContainsKey(name))
  56.             {
  57.                 var value = _fields[name];
  58.  
  59.                 try
  60.                 {
  61.                     output = (T)value;
  62.                 }
  63.                 catch
  64.                 {
  65.                     Debug.WriteLine("Failed to convert field '{0}' of type '{1}' to type '{2}'.", name, value.GetType().Name, typeof(T).Name);
  66.                 }
  67.             }
  68.  
  69.             return output;
  70.         }
  71.  
  72.         protected void SetField(object value, bool doNotify = true, [CallerMemberName] string property = "")
  73.         {
  74.             if (_fields == null)
  75.             {
  76.                 _fields = new Dictionary<string, object>();
  77.             }
  78.  
  79.             if (!_fields.ContainsKey(property))
  80.             {
  81.                 _fields.Add(property, value);
  82.             }
  83.             else
  84.             {
  85.                 _fields[property] = value;
  86.             }
  87.  
  88.             if (doNotify)
  89.             {
  90.                 OnPropertyChanged(property);
  91.             }
  92.         }
  93.  
  94.         #endregion
  95.  
  96.         #region Static UI Methods
  97.  
  98.         private static Dispatcher _ui;
  99.  
  100.         public static void SetUI()
  101.         {
  102.             if (_ui == null)
  103.             {
  104.                 _ui = Dispatcher.CurrentDispatcher;
  105.             }
  106.             else
  107.             {
  108.                 throw new Exception("Cannot set UI dispatcher more than once.");
  109.             }
  110.         }
  111.  
  112.         #endregion
  113.  
  114.         #region Public Events
  115.  
  116.         public event PropertyChangedEventHandler PropertyChanged;
  117.  
  118.         #endregion
  119.  
  120.         #region Public Methods
  121.  
  122.         public void OnPropertyChanged([CallerMemberName]string property = "")
  123.         {
  124.             PropertyChangedEventArgs args = null;
  125.  
  126.             if (_args == null)
  127.             {
  128.                 _args = new Dictionary<string, PropertyChangedEventArgs>();
  129.             }
  130.  
  131.             if (!_args.ContainsKey(property))
  132.             {
  133.                 _args.Add(property, args = new PropertyChangedEventArgs(property));
  134.             }
  135.             else
  136.             {
  137.                 args = _args[property];
  138.             }
  139.  
  140.             if (PropertyChanged != null)
  141.             {
  142.                 if (Dispatcher.CurrentDispatcher == _ui)
  143.                 {
  144.                     PropertyChanged(this, args);
  145.                 }
  146.                 else
  147.                 {
  148.                     _ui.BeginInvoke(new Action(() => PropertyChanged(this, args)));
  149.                 }
  150.             }
  151.         }
  152.  
  153.         #endregion
  154.     }
  155. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement