Programmatically binding an attached property in WPF

I'm using Jason Kemp's cool CueBanner class for "watermarking" text boxes in WPF:

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

Don't tell Ayn Rand

Jason's code creates a ContentPresenter programmatically, sets its content to the CueBanner.Content, adds the ContentPresenter to an Adorner subclass, and displays it when appropriate.

His code infers the ContentPresenter from padding and margin of the adorned control, but I added hpext:CueBanner.Padding instead so I could set it explicitly to a value I like better.

contentPresenter.Margin = CueBanner.GetPadding(adornedElement);

So far so good.

Here's the trouble: It works but I'd like to bind it instead.

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

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

But what do I use for a path for the source property? "hpext:CueBanner.Padding" doesn't work and it shouldn't work; that namespace doesn't exist there. No joy with "CueBanner.Padding" and "(CueBanner.Padding)". "MyProject.Extensions.CueBanner.Padding" doesn't work either and I can't see why it ought to.

I can't see anything that looks helpful in PropertyPath, but when I read that my mind starts to go a little blank.

I should be just doing this in XAML, shouldn't I?

Upvotes: 3

Views: 1452

Answers (2)

Clemens
Clemens

Reputation: 128013

You may directly create a PropertyPath from the attached property like this:

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

Upvotes: 13

Andy
Andy

Reputation: 30418

I think that the issue is that the source of the binding should be the TextBox, not the adornedElement. Based on this (which shows how to bind to Grid.Row via code), the binding should be created like this:

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

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

(Replace MyProject.Extensions.CueBanner.PaddingProperty with the actual AttachedProperty you registered.)

Upvotes: 1

Related Questions