可视树外的数据绑定。数据上下文桥接

时间:2011-04-13 09:26:57

标签: c# wpf xaml data-binding radchart

我正在尝试将动态行为绑定到WPF逻辑树和可视树之外的可视元素。

我的问题是RadChart绘图颜色是在(准路径)中给出的: RadChart.SeriesMapping.LineSeriesDefinition.Appearance.Stroke

我原本想将它绑定到XAML中图表datacontext的属性。天真地,我刚刚写了一个常规的{Binding PlotBrush}

编译器返回“找不到Governing FrameWorkelement”错误。在阅读之后,我认为这意味着在层次结构中解析datacontext不起作用。因为它的祖先(XAML说话)具有除Fra​​meWorkElement之外的其他类型和其他关系,而不是内容控件的内容。 至少,这是我目前对它的理解。请纠正我。

所以,我找到了“DataContext Bridge” http://www.codeproject.com/KB/WPF/AttachingVirtualBranches.aspx

简单地说,你绑定框架元素的datacontext属性,在运行时分配了datacontext(不是任何继承它的那些) datacontext资源中的 FrameWorkElement实例。然后使用相同的资源对象实例绑定到您希望“附加”到DataContext继承动态的“分支”的datacontext属性。但该文章的作者很幸运能够实现被观察财产的验证用户。 SolidColorBrush是密封的,我想即使使用装饰器也可以完成一个完整的画笔。

就我而言,这并没有帮助我做我想做的事,但我“非常接近”。所以我想知道是否有某些方面的XAML技巧可以帮助我。

<Window.Resources>
    <local:FrameWorkElement x:Key="DataContextBridge"/>
</Window.Resources>

但是,目前还不清楚我是如何利用它的。没有应该设置datacontext的对象。 AppearanceSettings不是FrameWorkElement。

<telerik:SeriesAppearanceSettings>
   <telerik:SeriesAppearanceSettings.Stroke>
       Ok, how do I use the fact that I can access the datacontext here?                                         
   </telerik:SeriesAppearanceSettings.Stroke>
</telerik:SeriesAppearanceSettings>

所以,下一步是我可以直接以某种方式得到画笔对象。我试验过这种事情,只是搞乱了:

.cs:

public class ObservableBrush : FrameworkElement
{
    public Brush Brush
    {
        get { return (Brush) GetValue(BrushProperty); }
        set { SetValue(BrushProperty, value); }
    }

    public static readonly DependencyProperty BrushProperty =
        DependencyProperty.Register("Brush", typeof (Brush), typeof (ObservableBrush), new UIPropertyMetadata(new SolidColorBrush(Colors.Black)));
}

XAML的顶部:

<Window.Resources>
    <local:ObservableBrush x:Key="StrokeBrush"/>
</Window.Resources>

内联XAML:

<telerik:SeriesAppearanceSettings.Stroke>
     <Binding Path="Brush">
     <Binding.Source>
          <Binding Source="{StaticResource ResourceKey=StrokeBrush}" Path="DataContext"/>
     </Binding.Source>                                            
     </Binding>                                     
</telerik:SeriesAppearanceSettings.Stroke>

“Binding”不是frameworkelement,也不是“Source”也是依赖属性,因此运行时当然会抱怨。我知道Brush属性不会返回除依赖项属性注册中给出的默认值以外的任何内容。

我有点在这个问题的第二天。我认为接下来的两次尝试将是: *使ObservableBrush成为一个真正的画笔。然后以编程方式设置它(有效地使用标准动态资源绑定)。我不喜欢它。我想做数据绑定工作。 *桥接BRUSH而不是DATACONTEXT。

XAML部分工作正常:

<telerik:SeriesAppearanceSettings.Stroke>
     <Binding Source="{StaticResource ResourceKey=StrokeBrush}" Path="Brush"/>
</telerik:SeriesAppearanceSettings.Stroke>

但是,如何将Brush绑定到DataContext属性?我是否可以在ObservableBrush中使用一些覆盖来使Brush动态地跟随datacontext中的一个?

如何在树中创建虚假的视觉元素,然后将TWO绑定与它相关联?

<!-- Within the visual tree scope -->
<SomeFrameWorkElementType>
     <SomeFrameWorkElemetType.SomeBrushProp>
         <Binding Source="{StaticResource ResourceKey=StrokeBrush}" Path="Brush" Mode="OneWayToSource"/>
         <Binding Stroke/>
     </SomeFrameWorkElemetType.SomeBrushProp>
<SomeFrameWorkElementType>

这会以某种方式“连接”两个绑定?

或者是否有一些(联合国)官方“助手类”用于此类功能?

或者我咆哮错误的树,并且(更好)通过动态资源绑定在代码隐藏中更好地解决这个问题?

有关如何继续这方面的任何想法或观察?除了在动态资源解决这个问题时坚持数据绑定的明显自我破坏性。

1 个答案:

答案 0 :(得分:12)

你在约什史密斯那里找到了一篇好文章,但它有点过时了。同一个人在一年之后写了一篇更好的文章,它涵盖了几乎相同的问题,但有更好的答案:Artificial Inheritance Context

在那里他使用了课程DataContextSpy,虽然我仍然没有完全得到你想要完成的东西,但我会试着告诉你如何使用它:

<Grid><!-- this is some container where its DataContext has the PlotBrush Property-->
    <Grid.Resources>
        <spy:DataContextSpy x:Key="Spy"/>
    </Grid.Resources>
    <telerik:thisIsYourControl>
        <telerik:SeriesAppearanceSettings.Stroke>
             <Binding Source="{StaticResource Spy}" Path="DataContext.PlotBrush"/>
        </telerik:SeriesAppearanceSettings.Stroke>
    </telerik:thisIsYourControl>
<Grid>

我希望这对您有所帮助。我之前没有使用过telerik控件,这就是我无法编写完整示例的原因,但仍希望能够覆盖它。