混合行为 - 你能绑定到他们的属性吗?

时间:2011-06-08 09:13:51

标签: wpf silverlight expression-blend attachedbehaviors

我目前正在将我创建的一些附加行为迁移到Blend Behaviors,以便它们支持在Expression Blend中拖放。我注意到Blend行为的作者倾向于将行为属性定义为依赖属性。

我创建了一个行为TiltBehaviour,它公开了一个double类型的公共依赖属性TiltFactor。在Expression Blend中我可以设置此属性的值,但是,添加“数据绑定...”的选项显示为灰色:

cannot bind to behaviour property

我还注意到行为扩展DependencyObject,因此它们没有DataContext,因此无法继承它们所附加的元素的DataContext。这对我来说真是个弱点!

所以,底线是,如果我无法在Blend中设置绑定到我的行为依赖属性,并且它不继承DataContext,为什么还要使用依赖属性呢?我可以改用CLR属性。

2 个答案:

答案 0 :(得分:8)

除非支持绑定,否则混合行为几乎无用!我重新创建了你的倾斜行为,它支持Blend 4中的绑定没有问题所以我不知道你到底出错了。也许您可以重现我的简单示例,然后推断您的设置有什么问题。

这是具有依赖属性的(非功能)倾斜行为:

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));
}

然后只需创建一个新窗口并将行为拖放到网格上,Blend就会创建:

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

和Blend“Data Binding ...”选项在属性选项卡中可用。

我用WPF和Silverlight项目测试了这个。内置的行为,触发器和动作都支持绑定,因为使用了依赖属性,所有Blend示例都使用了大量绑定,所以可以工作。

实际上,您可以将诸如FluidMoveBehavior之类的内置行为放到网格上,并检查Duration,它是一个依赖属性,支持绑定。如果这不起作用,我没有想法发生了什么!


让我们考虑一下绑定是如何对这些被称为行为的奇怪野兽起作用的。

作为WPF或Silverlight程序员,我们非常熟悉FrameworkElement之类的绑定。它有一个名为DataContext的属性,我们可以操作它来控制默认绑定源,当覆盖它时,该属性由嵌套元素继承。

但行为(以及触发器和操作)类型为FrameworkElement 。正如我们所料,它们最终来自DependencyObject。但是虽然我们可以对来自DependencyObject任何类使用绑定,但我们熟悉的DataContext在此低级别中缺失,因此绑定必须提供源。 那个不太方便。

所以行为(无论如何在WPF上)来自Animatable,而Animatable来自FreezableFreezable类是依赖对象的简单性与框架元素的复杂性相交的地方。 Freezable类也是更熟悉的东西(如画笔和图像源)的基类。这些类不需要框架元素的完整复杂性,但是他们希望以有限的方式参与与它们相关联的元素。

通过一个复杂的魔法过程,Freezable个实例获得了一个继承上下文:与它们关系最密切的框架元素,当使用默认绑定时(一个没有源),Freezable使用其相关元素的DataContext代替。

事实上,当你了解行为时,AssociatedObject是一个核心概念;对于行为,行为是附加到的事物。但重要的是,所有Freezable个对象都可以使用DataContext代理AssociatedObject

所有这些魔法都是Josh Smith所说的:

所有这一切导致说由于 Hillberg Freezable Trick ,Blend行为支持使用其关联元素的数据上下文作为默认源进行绑定。因此,对行为的绑定似乎“正常工作”而我们没有任何努力。由于这个原因,行为的用处是千倍。

答案 1 :(得分:4)

编辑: dain是正确的,你仍然可以绑定到人工创建的DataContext,你多久看到一个人绑定到SolidColorBrush.Color?即使SolidColorBrush继承自DependencyObject,因此也没有DataContext。

请参阅this blog post on the inheritance context

问题在于,由于附加了行为,它们不会出现在逻辑树中,因此无论如何都不会继承DataContext。