BindableBase.cs 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Runtime.CompilerServices;
  5. namespace TeamAAS
  6. {
  7. [Serializable]
  8. /// <summary>
  9. /// Implementation of <see cref="INotifyPropertyChanged"/> to simplify models.
  10. /// </summary>
  11. public abstract class BindableBase : INotifyPropertyChanged
  12. {
  13. [field: NonSerialized]
  14. /// <summary>
  15. /// Occurs when a property value changes.
  16. /// </summary>
  17. public event PropertyChangedEventHandler PropertyChanged;
  18. /// <summary>
  19. /// Checks if a property already matches a desired value. Sets the property and
  20. /// notifies listeners only when necessary.
  21. /// </summary>
  22. /// <typeparam name="T">Type of the property.</typeparam>
  23. /// <param name="storage">Reference to a property with both getter and setter.</param>
  24. /// <param name="value">Desired value for the property.</param>
  25. /// <param name="propertyName">Name of the property used to notify listeners. This
  26. /// value is optional and can be provided automatically when invoked from compilers that
  27. /// support CallerMemberName.</param>
  28. /// <returns>True if the value was changed, false if the existing value matched the
  29. /// desired value.</returns>
  30. protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
  31. {
  32. if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
  33. storage = value;
  34. RaisePropertyChanged(propertyName);
  35. return true;
  36. }
  37. /// <summary>
  38. /// Checks if a property already matches a desired value. Sets the property and
  39. /// notifies listeners only when necessary.
  40. /// </summary>
  41. /// <typeparam name="T">Type of the property.</typeparam>
  42. /// <param name="storage">Reference to a property with both getter and setter.</param>
  43. /// <param name="value">Desired value for the property.</param>
  44. /// <param name="propertyName">Name of the property used to notify listeners. This
  45. /// value is optional and can be provided automatically when invoked from compilers that
  46. /// support CallerMemberName.</param>
  47. /// <param name="onChanged">Action that is called after the property value has been changed.</param>
  48. /// <returns>True if the value was changed, false if the existing value matched the
  49. /// desired value.</returns>
  50. protected virtual bool SetProperty<T>(ref T storage, T value, Action onChanged, [CallerMemberName] string propertyName = null)
  51. {
  52. if (EqualityComparer<T>.Default.Equals(storage, value)) return false;
  53. storage = value;
  54. onChanged?.Invoke();
  55. RaisePropertyChanged(propertyName);
  56. return true;
  57. }
  58. /// <summary>
  59. /// Raises this object's PropertyChanged event.
  60. /// </summary>
  61. /// <param name="propertyName">Name of the property used to notify listeners. This
  62. /// value is optional and can be provided automatically when invoked from compilers
  63. /// that support <see cref="CallerMemberNameAttribute"/>.</param>
  64. protected void RaisePropertyChanged([CallerMemberName] string propertyName = null)
  65. {
  66. OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
  67. }
  68. /// <summary>
  69. /// Raises this object's PropertyChanged event.
  70. /// </summary>
  71. /// <param name="args">The PropertyChangedEventArgs</param>
  72. protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
  73. {
  74. PropertyChanged?.Invoke(this, args);
  75. }
  76. }
  77. }