Blend Behaviors - can you bind their properties?

I am currently migrating a few attached behaviors that I created for Blend Behaviors to support drag and drop in Expression Blend. I noticed that Blend behavior authors tend to define behavior properties as dependency properties.

I created a TiltBehaviour behavior that exposes a public dependency property, TiltFactor , of type double. In Expression Blend, I can set the value of this property, however the option to add a data binding ... is inactive:

cannot bind to behavior property

I also noticed that Behaviors extend DependencyObject , therefore they do not have a DataContext and therefore cannot inherit the DataContext element to which they are attached. It seems to me a real weakness!

So, the bottom line, if I canโ€™t bind to the dependency property of my behavior in Blend, and it does not inherit the DataContext , why use the dependency properties at all? Instead, I could use the CLR properties.

+7
source share
2 answers

Edit:. Right, you can bind to a DataContext, which is created artificially, how often have you seen how people bind to SolidColorBrush.Color ? It also works, although SolidColorBrush inherits from DependencyObject and therefore does not have a DataContext.

See this blog post for inheritance .

The fact is, since behavioral attachments are attached, they do not appear in the logical tree and, therefore, will not inherit the DataContext.

+4
source

Blend's behavior would be almost useless if they did not support binding! I recreated your slope behavior and supports snapping in Blend 4 without problems, so I donโ€™t know exactly where you did the wrong thing. Perhaps you can reproduce my simple example, and then indicate what is wrong with your setup.

Here is the (non-functional) tilt behavior with a dependency property:

 public class TiltBehavior : Behavior<FrameworkElement> { public double TiltFactor { get { return (double)GetValue(TiltFactorProperty); } set { SetValue(TiltFactorProperty, value); } } public static readonly DependencyProperty TiltFactorProperty = DependencyProperty.Register("TiltFactor", typeof(double), typeof(TiltBehavior), new UIPropertyMetadata(0.0)); } 

Then just create a new window and leave the behavior on the grid, and Blend will create this:

 <Grid> <i:Interaction.Behaviors> <local:TiltBehavior/> </i:Interaction.Behaviors> </Grid> 

and the Blend option "Data Binding ..." is available on the properties tab.

I tested this with both WPF projects and Silverlight. Built-in actions, triggers, and actions support binding through the use of dependency properties, and all Blend patterns use binding strongly, and therefore this one has .

In fact, you can simply add inline behavior, such as FluidMoveBehavior , to your grid and verify that Duration , which is a dependency property, supports binding. If this does not work, I have no idea what is happening!


Let's look then at how binding works for these strange animals called behavior.

As WPF or Silverlight programmers, we are very familiar with binding to things like FrameworkElement . It has a DataContext property that we can manipulate to control the default binding source, and this property is inherited by nested elements when we do not redefine it.

But the behavior (and triggers and actions) are not of type FrameworkElement . They are ultimately derived from DependencyObject , as you would expect. But although we can use the binding for any class derived from DependencyObject , our familiar DataContext not at this low-level level, so the binding should provide the source. This is not very convenient.

So the behavior (in WPF anyway) comes from Animatable and Animatable comes from Freezable . The Freezable class is a place where the simplicity of dependency objects intersects with the complexity of structure elements. The Freezable class is also the base class for more familiar things like brushes and image sources. These classes do not need the full complexity of the structure element, but they want to participate in the limited with the elements with which they are associated.

Using a complex magic process, Freezable instances acquire an inheritance context: it is most closely associated with the structure element, and when the default binding (one without a source) is used, Freezable uses this related element.

In fact, when you learn about behavior, AssociatedObject is a central concept; for behavior, this is what behavior is attached to. But itโ€™s important that all Freezable objects can use their AssociatedObject 's DataContext by proxy.

All this magic - this Josh Smith causes:

So, all this leads to the assertion that due to Hillberg freezing, the Blend behavior supports binding, using the data context of the element associated with them as the default source. As a result of attachment to behavior, it seems that they โ€œjust workโ€ without any effort on our part. Because of this, behavior is a thousand times more useful.

+8
source

All Articles