This blog post is just to document my experience with the Expression Blend Sample source together with Silverlight 4 or WPF 4.0
If you are using the Expression Blend Samples from codeplex (http://expressionblend.codeplex.com) then you might experience some problems when using the included triggers and behavior within SL4 or WPF4 runtime. The problem is that a dependency property with the type System.Windows.Data.Binding is not set to due to a change in the MS.Internal.Data.DynamicValueConverter class. Since SL4 / WPF4 the DynamicValueConverter uses the value of the binding instead of the binding instance itself. As example, the Command property of the InvokeDataCommand trigger is declared as System.Windows.Data.Binding, but the DynamicValueConverter will return the value of the binding, an ICommand compatible instance, and not the binding instance itself. So, the command property will always be null, because DynamicValueConverter cannot cast the object. And if the command binding cannot be set, the BindingListener, which is used internally, will not work correctly.
If we change the binding target from a dependency property to a simple CLR property, then the DynamicValueConverter can set the property and InvokeDataCommand works as before.
I’ve found that codeplex user AvdMeulen changed the whole Expression sample source and submitted a zip package on codeplex. See link below.
Let’s go into more details:
Silverlight 3 does not allow using data binding on types which are NOT inherited from class FrameworkElement. That means that the entire Silverlight standard behaviors and triggers do not support data binding, because the Trigger and Behavior classes are directly derived from DepedencyObject. Nevertheless, if you use data-binding with a trigger- or behavior property in Silverlight 3, then the binding system does not execute the binding, but it tries to set the binding instance itself to the property as a value of type System.Windows.Data.Binding. This will be done through the MS.Internal.Data.DynamicValueConverter class. If the target property is not of type System.Windows.Data.Binding it will not work and you get an AG_E_PARSER_BAD_PROPERTY_VALUE exception from the XAML parser. Based on this binding-engine behavior, Pete Blois invented the BindingListener class.
His trick was to declare properties on behaviors and triggers as type of System.Windows.Data.Binding in order to get them bindable. The binding is still not executed by the binding system and to bind them he declared a dummy attached dependency property and set the binding instance to the attached dependency property. The result is that the attached dependency property can execute the binding and we can just listen to when the attached dependency property changes. This results in a full functional binding for non-FrameworkElements. All this is encapsulated in the BindingListener class.
But now, why it does not work for SL4 anymore? The answer can be found in the breaking changes for Silverlight 4.
With SL4 it’s now possible to data binding dependency properties on triggers and behavior too, which makes the BindingListener class useless. This is also the reason why the Binding property remains null, because the SL4 binding engine set a BindingExpression and not the Binding itselfs and the BindingExpression tries to set the Command value instead of the Binding instance.