Tuesday, October 13, 2009

Adventures while building a Silverlight Enterprise application part #26

The other day I ran into a scenario where I would need to databind to some primitive type variables like a bool or a string. As I didn't want to build class after class to solve this, I sought after a more generic solution. This article describes that solution.

The requirements
The requirements are simple:
  • I should be able to databind to any primitive type
  • The solution should be easy to use
  • The solution should require as little code as possible
Analysis
Analyzing this I quickly realized a generic class, wrapping the actual variable might would be a nice solution. I started with this:
public class BindableObject<T>

A simple class declaration taking in any type. Obviously I needed the class to support binding to it's properties, so I included the INotifyPropertyChanged interface in the declaration and I implemented the PropertyChanged event and a method to trigger that event.
I also needed to expose a property to contain the actual value, so I included the Value property and it's private field.

Now I would write something like:
BindableObject<bool> someObject = new BindableObject<bool>();
Binding someBinding = new Binding("Value");
someBinding.Source = someObject;
someBinding.Mode = BindingMode.TwoWay;
textBox1.SetBinding(TextBox.IsEnabledProperty, someBinding);

As you can see, this is still quite elaborate. I decided on adding a method to do the binding inside the BindableObject class. I ended up with a class that looks like this:

public class BindableObject<T> : INotifyPropertyChanged
{
private T _value;

public T Value
{
get
{
return _value;
}
set
{
_value = value;
DoPropertyChanged("Value");
}
}

public void BindTo(FrameworkElement element, DependencyProperty property, BindingMode mode)
{
Binding binding = newBinding("Value");
binding.Source = this;
binding.Mode = mode;
element.SetBinding(property, binding);
}

#region INotifyPropertyChanged Members

private void DoPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged.Invoke(this, newPropertyChangedEventArgs(propertyName));
}
}

public event PropertyChangedEventHandler PropertyChanged;

#endregion
}

It's a fairly simple class. You can now write the previous example like this:
BindableObject<bool> someObject = new BindableObject<bool>();
someObject.BindTo(textBox1, TextBox.IsEnabledProperty, BindingMode.TwoWay);

I'm pretty happy with this and I hope it proves useful to you too.

No comments:

Post a Comment