DependencyObject绕过DependencyProperty系统?

时间:2013-10-02 18:44:53

标签: c# wpf xaml dependency-properties dependencyobject

我有以下课程:

public class ValueMarker : DependencyObject
{
    public static readonly DependencyProperty BrushProperty = DependencyProperty.Register("Brush", typeof(Brush), typeof(ValueMarker), new FrameworkPropertyMetadata(Brushes.Aqua));
    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(ValueMarker), new FrameworkPropertyMetadata(0d));
    public static readonly DependencyProperty OffsetProperty = DependencyProperty.Register("Offset", typeof(double), typeof(ValueMarker), new FrameworkPropertyMetadata(0d));

    public Brush Brush
    {
        get { return (Brush)GetValue(BrushProperty); }
        set { SetValue(BrushProperty, value); }
    }

    public double Offset
    {
        get { return (double)GetValue(OffsetProperty); }
        set { SetValue(OffsetProperty, value); }
    }

    public double Value
    {
        get { return (double)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }
}

在XAML中,我创建了一些资源数组,其中包含一些绑定:

        <x:Array Type="my:ValueMarker" x:Key="plainMarks">
            <my:ValueMarker Brush="Red" Offset="-5" Value="{Binding Path=...}" />
            <my:ValueMarker Brush="Orange" Offset="-5" Value="{Binding Path=...}"/>
            <my:ValueMarker Brush="Orange" Offset="-5" Value="{Binding Path=...}"/>
            <my:ValueMarker Brush="Red" Offset="-5" Value="{Binding Path=...}" />
        </x:Array>

在调试绑定时,我注意到如果我删除了DP的setter,XAML会显示一个错误,说明该属性丢失了。据我所知,XAML使用DP系统分配值,从而实现绑定。在这种情况下,如果XAML期望“正常”属性,则绑定是不可能的。任何人都可以告诉我如何使它工作?

1 个答案:

答案 0 :(得分:1)

您无法在此绑定ValueMarkers的原因是:

1.它们不在您的窗口/用户控件的VisualTree中。

2.它们不是可以继承DataContext的Type的对象,即使它们不是Visual Tree的一部分。

因此,为了使您的ValueMarkers绑定到View DataContext中的属性,首先您必须从Freezable类派生它们,如下所示:

 public class ValueMarker : Freezable
    {
        //All your Dependency Properties comes here//

        protected override Freezable CreateInstanceCore()
        {
            return new ValueMarker();
        }
    }

完成此操作后,您可以简单地绑定您的对象,如下所示:

   <my:ValueMarker x:Key="vm1" Brush="Orange" Offset="-5" Value="{Binding Path=Text1}"/>

此处Text1是Windows / usercontrols DataContext

中的属性

然后您可以将此资源用作:

  <TextBox Text="{Binding Value, Source={StaticResource vm1}, StringFormat=F2}"/>

同样,您可以为其他ValueMarkers创建资源,以便在绑定中使用它们。

您将无法通过创建x:Array来进行绑定,因为x:Array不在于visualtree,并且不继承DataContext,因此其元素也无法访问它。

如果您仍然想要使用其元素应该支持绑定的集合,那么您将需要创建自己的集合类,该集合类应该继承Freezable并公开DependancyProperty以捕获DataContext并将其设置在子元素上。