Which architecture?
For 1-way binding, you don't need anything other than public properties - and maybe some TypeConverter
implementations for any bespoke data types (struct
s etc)
For full 2-way binding, you'll need an eventing implementation - any of:
- a "public event EventHandler FooChanged" for every property "Foo"
- an `INotifyPropertyChanged implementation
- a bespoke component-model (don't go there - overkill)
For an example of a INotifyPropertyChanged
implementation (note you might want to move some of the code for re-use) :
public class Foo : INotifyPropertyChanged
{
private string bar;
public string Bar
{
get { return bar; }
set { UpdateField(ref bar, value, "Bar"); }
}
// other properties...
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null) PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
protected bool UpdateField<T>(ref T field, T value,
string propertyName)
{
if (!EqualityComparer<T>.Default.Equals(field, value))
{
field = value;
OnPropertyChanged(propertyName);
return true;
}
return false;
}
}
To bind sets of data (grids etc), the easiest thing is to use generics; basically, the minumum is IList
- but you get extra metadata from a public T this[int index]
indexer - which List<T>
, Collection<T>
etc all have. More - BindingList<T>
implements IBindingList
allowing collection-based notification events (but only to INotifyPropertyChanged
- not to the FooChanged
pattern).