Making a generic UpdateSourceTrigger for PropertyChanged in Silverlight

In my previous post I explained how Silverlight 4 lacks the UpdateSourceTrigger for PropertyChanged. I focused on how you can overcome this issue for one of the biggest use cases, which is the TextBox.

In this post I will show how one can do this for any Dependency Property of any Framework element. Please note that this post is quite an experimental one. Probably the use case you are looking for is for the textbox scenario, if that is the case I would suggest that you use the more explicit approach i.e the one I show in my previous post. The take away from this post should be more the idea of how things work rather than the actual code I am using here, this code was never tested in production thus it might contain memory leaks and other issues.

The key for updating the binding when a property changes is to actually know when the property has changed and then force the binding to update the source. In WPF there are multiple ways of doing this, one of which is to use the DependencyPropertyDescriptor class. This class allows you to hook an event handler for when the specified property has changed. Unfortunately in Silverlight there is no DependencyPropertyDescriptor class thus one has to resort to some ninja trick Smile After doing some internet crawling I found an interesting approach using attached property creating and hooking to the property changed. The idea is that you create an attached property and you bind the newly created attached property to the property that is consuming the binding.

Let’s dig a bit deeper

Let’s say you have the following binding

<TextBox Text=”{Binding SomeText, Mode=TwoWay}”

The Text dependency property is consuming a binding and you want to update the source of the binding as soon as the property changes.

You create an attached property and you bind it to the Text property of that TextBox. This will get you notified when the text changes because when creating the attached property you can have a property changed handler. In the property changed handler you update the source of the binding.

You would create the attached property and the binding for notifications like so

// Create attached property

var listeningProperty = System.Windows.DependencyProperty.RegisterAttached(

    "ListenAttached" + propertyName,

    typeof(object),

    typeof(UpdateSourceTriggerProxy),

    new System.Windows.PropertyMetadata(OnPropertyChanged));


//Create a binding that will be updated when the property changes

var listeningBinding = new Binding(propertyName) { Source = element };

element.SetBinding(listeningProperty,

    listeningBinding);

Ok so I showed how you can workaround the lack of DependencyPropertyDescriptor in Silverlight for property changed notification, now how do we update the binding?

In order to do this we will need to get the instance of the Text Dependency Property. Unfortunately we will need to resort to reflection in order to get the instance of the Dependency property. We can do this by name

var propertyFieldInfo = frameworkElement.GetType().GetField(newPropertyName + "Property");

if (propertyFieldInfo == null)

    throw new InvalidOperationException(String.Format(

        "The property {0} does not exist in the element {1}. Make sure you specified the correct property.",

        newPropertyName, frameworkElement.GetType().FullName));

//Get the dependency property the binding is applied to

var property = (DependencyProperty)

    propertyFieldInfo.GetValue(frameworkElement);

As you can see I am attaching a string “Property” to the actual property name (in this case Text) when I try to get the dependency property by reflection. Even though in XAML you specify “Text” as the property name, the actual dependency property name is TextProperty (which is a coding standard for dependency properties), “Text” is how the property is registered to the framework.

So why did we need to get the actual instance of the Dependency property? We had to do this in order to get the Binding Expression so that we can force the binding expression to update the source of the binding with the new property value. This would look like this

_bindingExpression = element.GetBindingExpression(BoundProperty);

And to update the source (i.e in the property changed handler of the attached property) we would do this

_bindingExpression.UpdateSource();

How is this approach generic?

Well let’s see what we did in the “Dig Deeper” section.

– We are getting a dependency property by name

– We get the Binding Expression from that dependency property

– We create an attached property which will be our way of hooking to property changes of a specific dependency property.

mmm… So as such we can have 1 attached property of type string that will generate this hook and update the source for us. If we do this we would have something like this in our XAML

<TextBox Text=”{Binding SomeText, Mode=TwoWay}” local:UpdateSourceTrigger.PropertyName=”Text” />

Not great but not too bad, it will do the trick for now… So here is the code for the attached property (you have to download the sample project)… Its exactly what I explained in the section above.

Please note that I am creating the hook inside a separate class UpdateSourceTriggerProxy. I am doing that so that the operation is atomic and everytime you use this approach we have a different instance of UpdateSourceTriggerProxy doing the hook for updates and the actual update. The object instance we be kept alive because of the property changed delegate.

Download sample project here.

7 thoughts on “Making a generic UpdateSourceTrigger for PropertyChanged in Silverlight

  1. Pingback: Making a generic UpdateSourceTrigger for PropertyChanged in Silverlight | www.nalli.net

  2. Pingback: Making a generic UpdateSourceTrigger for PropertyChanged in Silverlight

  3. Creating that DependencyProperty ListenAttached has two problems.. First if you want to apply that to two controls if will fail as you can’t register two DependencyProperties with the same name. Ex: If you have two textboxes using the attached property ListenAttachedTextBox…

    Second issue is a MemoryLeak… if you are using this on controls that are going to be removed the created dependencyproperty will still have a root throught the propertychangedCallback..

    Need to create the ListenAttached DP static( that way you will only register this once, also only one DP gets registered, not one per Property), then with the UpdateSourceTrigger DP make a subscription to the Loaded/unloaded and then setBinding and ClearValue ( solves the memory leak)

  4. For information, it isn’t working in Design mode in Visual 2010 … It crashes in UpdateSourcetriggerProxy.OnPropertyChanged with NullPointerException … I corrected it by adding if (_bindingExpression != null).

Leave a reply to Jonas Mayor Cancel reply