可视化树之外的数据绑定.数据上下文桥接

本文关键字:数据 上下文 桥接 数据绑定 可视化 | 更新日期: 2023-09-27 17:50:08

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

我的问题是,RadChart图的颜色是给定的(准路径):RadChart.SeriesMapping.LineSeriesDefinition.Appearance.Stroke

我最初想将其绑定到XAML中图表数据上下文的属性。我只是天真地写了一个常规的{Binding PlotBrush}

编译器返回"Cannot Find Governing FrameWorkelement"错误。在阅读之后,我认为这意味着在层次结构中解析数据上下文不起作用。因为它的祖先(从XAML的角度来说)有不同于FrameWorkElement的类型和不同于内容控件内容的关系。至少,这是我目前的理解。请纠正我。

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

简单地说,它表示您绑定框架元素的数据上下文属性,该属性在运行时分配了数据上下文(而不是继承它的任何数据上下文)资源中的FrameWorkElement实例的数据上下文。然后,使用相同的资源对象实例绑定到希望"附加"到datacontext继承动态的"分支"的数据上下文属性。但是本文的作者有能力实现观察到的属性的validationrule消费者。SolidColorBrush是密封的,我想这将是相当多的工作来实现一个完整的刷,甚至使用装饰器。

在我的情况下,这并不能帮助我做我想做的,但我"如此接近"。所以我想知道是否有一些XAML的技巧可以帮助我。

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

然而,我不清楚如何利用它。没有应该设置其数据上下文的对象。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)));
}

Top of 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"不是一个框架元素,"Source"也不是一个依赖属性,所以运行时当然会抱怨。我知道Brush属性永远不会返回依赖属性注册中给定的默认值以外的任何值。

这个问题我第二天就开始了。我想我接下来的两个尝试是:*让ObservableBrush成为一个实际的画笔。然后以编程方式设置它(有效地使用标准动态资源绑定代替)。我不喜欢它。我想让数据绑定工作。*桥接一个刷而不是DATACONTEXT。

XAML部分工作正常:

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

但是,我如何将画笔绑定到DataContext属性?是否有一些重写,我可以在ObservableBrush中使用,使画笔动态跟随数据上下文中的一个?

如何在树中创建一个假的视觉元素,然后将两个绑定关联到它?

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

这会以某种方式"连接"两个绑定吗?

或者有一些(非)官方的"助手类"用于这种类型的功能?

还是我找错了树,并且(更好)通过动态资源绑定在代码隐藏中解决这个问题?

关于如何继续下去有什么想法或观察吗?当动态资源应该解决这个问题时,我坚持数据绑定,这显然是自我毁灭。

可视化树之外的数据绑定.数据上下文桥接

你在那里找到了Josh Smith写的一篇好文章,但是有点过时了。同一个人在大约一年后写了一篇更好的文章,涵盖了几乎相同的问题,但有更好的答案:人工继承上下文

他使用了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>

我希望这对你有帮助和工作。我以前没有使用过teleerik控件,这就是为什么我不能编写一个完整的示例,仍然希望这涵盖了它。