8

我正在尝试将动态行为绑定到 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

简单地说,您将在运行时分配 datacontext(不是任何继承它的那些)的框架元素的 datacontext 属性绑定资源中 FrameWorkElement 实例的 datacontext 。然后使用相同的资源对象实例绑定到您希望“附加”到 DataContext 继承动态的“分支”的 datacontext 属性。但是文章的作者有幸能够实现观察到的属性的验证规则消费者。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)));
}

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>

“绑定”不是框架元素,“源”也不是依赖属性,所以运行时当然会抱怨。我知道 Brush 属性不会返回除依赖属性注册中给出的默认值之外的任何内容。

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

XAML 部分工作正常:

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

但同样,如何将 Brush 绑定到 DataContext 属性?我可以在 ObservableBrush 中使用一些覆盖来使 Brush 动态跟随数据上下文中的那个吗?

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

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

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

或者这种功能是否有一些(非)官方的“帮助类”?

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

关于如何继续进行此操作的任何想法或意见?除了我在动态资源应该解决这个问题时坚持数据绑定的明显自我毁灭性。

4

1 回答 1

13

你在那里找到了 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>

I hope this helps and works for you. I have not used telerik controls before, that's why I can't code a complete example, still hope this covers it.

于 2011-04-13T10:03:08.710 回答