【问题标题】:Blend Behaviours - can you bind to their properties?混合行为 - 你能绑定到它们的属性吗?
【发布时间】:2011-06-08 09:13:50
【问题描述】:

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

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

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

因此,底线是,如果我无法在 Blend 中设置与我的行为依赖属性的绑定,并且它没有继承 DataContext,那么为什么还要使用依赖属性呢?我可以只使用 CLR 属性。

【问题讨论】:

  • 这很奇怪,它是什么版本的Blend?我使用 Blend 4 + Silverlight 4 将元素属性或 DataContext 属性绑定到行为的依赖属性没有问题...
  • Dain,我已经尝试在 Visual Studio 中手动绑定,例如TiltFactor="{Binding}" 这会导致 AG_E_PARSER_BAD_PROPERTY_VALUE,这通常表明您正在绑定到非依赖属性。您能指出网络上绑定行为属性的示例吗?
  • 您必须绑定到正确类型的具体属性:TiltFactor="{Binding TiltFactor}"
  • Dain ...这取决于您的 DataContext 是什么,在上面的示例中,我将要附加的元素的 DataContext 设置为双精度,例如Rectangle.DataContext = 10.0,因此 TiltFactor="{Binding}" 的绑定,没有属性路径是完全有效的。无论如何,我尝试了您的建议 TiltFactor="{Binding TiltFactor}" ,仍然没有乐趣! .... 也许这是 VS / Silverlight for Windows Phone 7 中的一个特定问题。
  • 啊,抱歉...没办法了,它适用于我的 SL4,即使是隐式继承的 DataContext。

标签: wpf silverlight expression-blend attachedbehaviors


【解决方案1】:

除非支持绑定,否则混合行为几乎毫无用处!我重新创建了您的倾斜行为,它支持在 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>

属性选项卡中提供了混合“数据绑定...”选项。

我使用 WPF 和 Silverlight 项目对此进行了测试。内置的行为、触发器和动作都通过使用依赖属性来支持绑定,并且所有 Blend 示例都大量使用绑定,因此 必须 起作用。

事实上,您可以将像FluidMoveBehavior 这样的内置行为拖放到您的网格中,然后检查Duration(它是一个依赖属性)是否支持绑定。如果这不起作用,我知道发生了什么!


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

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

但行为(以及触发器和操作)属于FrameworkElement 类型。正如我们所料,它们最终源自DependencyObject。但是,虽然我们可以在派生自DependencyObjectany 类上使用绑定,但我们熟悉的DataContext 在这个低级别缺失,因此绑定必须提供源代码。 不太方便。

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

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

事实上,当您了解行为时,AssociatedObject 是一个中心概念;对于行为,它是行为所依附的事物。但重要的一点是,所有Freezable 对象都可以通过代理使用其AssociatedObjectDataContext

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

所有这一切都导致说,由于Hillberg Freezable Trick,Blend 行为支持使用其关联元素的数据上下文作为默认源进行绑定。结果,行为绑定似乎“正常工作”,无需我们付出任何努力。因此,行为的用处要大一千倍。

【讨论】:

    【解决方案2】:

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

    this blog post on the inheritance context

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

    【讨论】:

    • +1 获取关于继承上下文的博文。为什么我以前没见过?!很棒的东西。
    • 然而......他们可以继承 DataContext,根据这篇博文:scottlogic.co.uk/blog/colin/2010/05/…
    • 奇怪的是,这些信息要么不在文档中,要么很难找到。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 2017-10-29
    • 2023-04-03
    • 2010-10-24
    • 1970-01-01
    相关资源
    最近更新 更多