在 WPF 中以编程方式绑定附加的 属性

Programmatically binding an attached property in WPF

我在 WPF 中将 Jason Kemp's cool CueBanner class 用于 "watermarking" 文本框:

<TextBox 
    hpext:CueBanner.Content="Find Text"
    hpext:CueBanner.Padding="2,6,0,0"
    />

Jason 的代码以编程方式创建 ContentPresenter,将其内容设置为 CueBanner.Content,将 ContentPresenter 添加到 Adorner 子类,并在适当的时候显示它。

他的代码从装饰控件的填充和边距推断出 ContentPresenter,但我添加了 hpext:CueBanner.Padding,因此我可以将其明确设置为我更喜欢的值。

contentPresenter.Margin = CueBanner.GetPadding(adornedElement);

到目前为止一切顺利。

问题来了:它可以工作,但我想改为绑定它。

var binding = new Binding("hpext:CueBanner.Padding") { Source = adornedElement };

BindingOperations.SetBinding(contentPresenter, ContentPresenter.MarginProperty, binding);

但是我用什么作为源路径 属性? "hpext:CueBanner.Padding" 不起作用,也不应该起作用;该命名空间在那里不存在。 "CueBanner.Padding""(CueBanner.Padding)" 不快乐。 "MyProject.Extensions.CueBanner.Padding" 也不起作用,我不明白为什么它应该起作用。

我在 PropertyPath 中看不到任何有用的内容,但当我读到这些内容时,我的脑子开始变得有点空白。

我应该在 XAML 中这样做,不是吗?

我认为问题在于绑定源应该是 TextBox,而不是 adornedElement。基于 this(展示了如何通过代码绑定到 Grid.Row),绑定应该像这样创建:

var binding = new Binding("(CueBanner.Padding)") { Source = textbox };

BindingOperations.SetBinding(textBox, MyProject.Extensions.CueBanner.PaddingProperty, binding);

(将 MyProject.Extensions.CueBanner.PaddingProperty 替换为您实际注册的 AttachedProperty。)

您可以直接从附加的 属性 创建 PropertyPath,如下所示:

var binding = new Binding
{
    Path = new PropertyPath(CueBanner.PaddingProperty), // here
    Source = adornedElement
};