Skip to content

Instantly share code, notes, and snippets.

@josheinstein
Created June 6, 2012 15:05
Show Gist options
  • Save josheinstein/2882437 to your computer and use it in GitHub Desktop.
Save josheinstein/2882437 to your computer and use it in GitHub Desktop.
No-frills INPC base class in C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace Einstein
{
/// <summary>
/// A thin base class that provides a simple property change notification mechanism so
/// that the object can easily participate in data binding.
/// </summary>
public abstract class ObservableBase : INotifyPropertyChanged, INotifyPropertyChanging
{
#region Constructors
/// <summary>
/// Default constructor.
/// </summary>
protected ObservableBase( )
{
}
#endregion
#region Methods
/// <summary>
/// Sets the value of the <paramref name="field"/> to the new value and raises the appropriate
/// property change notifications.
/// </summary>
/// <typeparam name="T">The type of the field to be set.</typeparam>
/// <param name="propertyName">The name of the property that will be communicated in the property change event.</param>
/// <param name="field">The field to set, passed by reference.</param>
/// <param name="newValue">The new value to set on the field.</param>
/// <returns>True if the field was changed, false if the new value was the same as the old value.</returns>
protected bool SetField<T>( string propertyName, ref T field, T newValue )
{
if ( EqualityComparer<T>.Default.Equals( field, newValue ) ) {
return false;
}
OnPropertyChanging( propertyName );
field = newValue;
OnPropertyChanged( propertyName );
return true;
}
/// <summary>
/// Raises the <see cref="E:PropertyChanging"/> event.
/// </summary>
/// <param name="propertyName">The name of the property that is changing.</param>
protected virtual void OnPropertyChanging( string propertyName )
{
var handler = PropertyChanging;
if ( handler != null ) {
handler( this, new PropertyChangingEventArgs( propertyName ) );
}
}
/// <summary>
/// Raises the <see cref="E:PropertyChanged"/> event.
/// </summary>
/// <param name="propertyName">The name of the property that changed.</param>
protected virtual void OnPropertyChanged( string propertyName )
{
var handler = PropertyChanged;
if ( handler != null ) {
handler( this, new PropertyChangedEventArgs( propertyName ) );
}
}
#endregion
#region Events
/// <summary>
/// Event that is raised before the property is changed.
/// </summary>
public event PropertyChangingEventHandler PropertyChanging;
/// <summary>
/// Event that is raised after a property is changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
}
using System;
namespace Einstein {
/// <summary>
/// Example of using the ObservableBase class with an object that backs its properties
/// with ordinary fields.
/// </summary>
/// <remarks>
/// This example demonstrates the use of a very simple and lightweight ObservableBase class. There
/// are numerous ways to implement INotifyPropertyChanged in a class. Some involve using lambda
/// expressions. Some involve using reflection. Some involve using a property bag backing store.
/// This one is probably the simplest to implement with minimal dependence on other classes.
/// The guts of ObservableBase could easily be copied into your POCO's instead.
/// </remarks>
public class Person : ObservableBase {
private string _FirstName;
private string _LastName
private int _Age;
public string FirstName {
get {
return _FirstName;
}
set {
if (SetField("FirstName", ref _FirstName, value)) {
OnPropertyChanged("FullName");
}
}
}
public string LastName {
get {
return _LastName;
}
set {
if (SetField("LastName", ref _LastName, value)) {
OnPropertyChanged("FullName");
}
}
}
/// <summary>
/// Note that changing either the FirstName or LastName properties will result in
/// a change notification for the FullName property as well.
/// </summary>
public string FullName {
get {
return FirstName + " " + LastName;
}
}
public int Age {
get {
return _Age;
}
set {
SetField("Age", ref _Age, value);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment