WPF绑定到视觉树中某个附加属性

4

我有一个附加属性ZoneBackground。这可以在任何框架元素上注意到。

现在我有一个样式ZonedTextBox。这应该将ZoneBackground的值应用于文本框。关键是:样式不知道 ZoneBackground在可视层次结构中的位置,并且位于哪个元素上。

是否可以搜索第一个具有ZoneBackground值并使用该值的父级?

我得到了这个XAML:

<Grid controls:ZoneStylingBehavior.ZoneBackground="Red">
    ...
    <TextBox Background="{Binding controls:ZoneStylingBehavior.ZoneBackground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}}" />
    ...
</Grid>

这不起作用,而且我希望能够在可视树的任何位置上标注ZoneBackground,比如在StackPanelGrid上,甚至可能多次。


更新:按照建议,我尝试了使用依赖属性继承。这个想法听起来很棒,但我还没有成功。

依赖属性声明:

public static readonly DependencyProperty ZoneBackgroundProperty = DependencyProperty.RegisterAttached("ZoneBackground", typeof(Brush), typeof(ZoneStylingBehavior), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));

XAML代码如下:
<StackPanel>
    <Grid controls:ZoneStylingBehavior.ZoneBackground="{StaticResource BrushGreen}">
         ...
         <Label Background="{Binding controls:ZoneStylingBehavior.ZoneBackground, RelativeSource={RelativeSource Self}, PresentationTraceSources.TraceLevel=High}" Content="test" />
         ...
    </Grid>
    ...
    <Grid controls:ZoneStylingBehavior.ZoneBackground="{StaticResource BrushRed}">
        ...
    </Grid>
</StackPanel>

控制台输出:
System.Windows.Data Error: 40 : BindingExpression path error: 'controls:ZoneStylingBehavior' property not found on 'object' ''TextBox' (Name='')'. BindingExpression:Path=controls:ZoneStylingBehavior.ZoneBackground; DataItem='TextBox' (Name=''); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String')

级别为的绑定跟踪显示:
System.Windows.Data Warning: 56 : Created BindingExpression (hash=17086942) for Binding (hash=33055417)
System.Windows.Data Warning: 58 :   Path: 'controls:ZoneStylingBehavior.ZoneBackground'
System.Windows.Data Warning: 60 : BindingExpression (hash=17086942): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=17086942): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=17086942): Attach to System.Windows.Controls.Label.Background (hash=18524697)
System.Windows.Data Warning: 67 : BindingExpression (hash=17086942): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=17086942): Found data context element: <null> (OK)
System.Windows.Data Warning: 72 :   RelativeSource.Self found Label (hash=18524697)
System.Windows.Data Warning: 78 : BindingExpression (hash=17086942): Activate with root item Label (hash=18524697)
System.Windows.Data Warning: 108 : BindingExpression (hash=17086942):   At level 0 - for Label.controls:ZoneStylingBehavior found accessor <null>
System.Windows.Data Error: 40 : BindingExpression path error: 'controls:ZoneStylingBehavior' property not found on 'object' ''Label' (Name='')'. BindingExpression:Path=controls:ZoneStylingBehavior.ZoneBackground; DataItem='Label' (Name=''); target element is 'Label' (Name=''); target property is 'Background' (type 'Brush')
System.Windows.Data Warning: 103 : BindingExpression (hash=17086942): Replace item at level 1 with {NullDataItem}
System.Windows.Data Warning: 80 : BindingExpression (hash=17086942): TransferValue - got raw value {DependencyProperty.UnsetValue}
System.Windows.Data Warning: 88 : BindingExpression (hash=17086942): TransferValue - using fallback/default value <null>
System.Windows.Data Warning: 89 : BindingExpression (hash=17086942): TransferValue - using final value <null>

有人能指出问题在哪里吗?


1
要不把ZoneBackground设置为继承属性,那么你只需要做像这样的事情: <TextBox Background="{Binding controls:ZoneStylingBehavior.ZoneBackground, RelativeSource={RelativeSource Self}" /> - elios264
1个回答

5

在注册附加属性时,将附加属性设置为默认继承值,而不是在可视树中搜索设置此值的第一个父级,方法是设置FrameworkPropertyMetadataOptions.Inherits标志。

示例:

public static readonly DependencyProperty ZoneBackgroundProperty =
         DependencyProperty.RegisterAttached("ZoneBackground",
                                      typeof(Brush), typeof(ZoneStylingBehavior),
       new FrameworkPropertyMetadata(FrameworkPropertyMetadataOptions.Inherits));

因此,这样它将自动从可视树中的第一个具有附加属性值的父级继承该值。 (DataContext DP也是如此) 更新
对于附加属性绑定,您需要将绑定包装在括号中。
<Label Background="{Binding (controls:ZoneStylingBehavior.ZoneBackground), 
                            RelativeSource={RelativeSource Self}}"
       Content="test"/>

那看起来是个好主意:不幸的是,我没能让它工作。也许我漏掉了一些小细节。我更新了问题。 - ZoolWay
1
@ZoolWay - 请查看答案更新以回答您的后续问题。 - Rohit Vats
哦,没注意到!谢谢你指出这个语法问题! :) - ZoolWay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接