views:

47

answers:

3

I'm trying what should be an easy bind in my user control:

<UserControl x:Class="MyApp.FlowNode" ...>
    <StackPanel>
        <Label Content="{Binding Path=Header, RelativeSource={RelativeSource Self}}" />
    </StackPanel>
</UserControl>

With the underlying code being:

public partial class FlowNode : UserControl
{
    public FlowNode()
    {
        InitializeComponent();
    }

    public string Header { get { return "Testing"; } };
}

However, the label stays blank. What am I doing wrong?

A: 

In your constructor, set the DataContext of the UserControl to itself. "this.DataContext = this". And remove the RelativeSource in your binding.

karmicpuppet
You should never do this in a UserControl - it's a recipe for bugs. When you set the DataContext to itself you break any Bindings set on an instance of the control that use the inherited DataContext by overridding the inherited value. Since you're doing it from inside it's impossible to see from the XAML that's using the control. Instead set the DataContext of a named element in the UserControl's XAML, like a root Grid.
John Bowen
I definitely agree in your comment about "this.DataContext = this" is generally not a good design practice, I guess I'm just suggesting to the OP that this is the most direct way to fix his problem based on the facts he gave above. =)
karmicpuppet
+2  A: 

{RelativeSource Self} refers to the Label instance, not your user control.

Instead of using a RelativeSource, you should set the UserControl's DataContext to itself, as karmicpuppet suggested.

SLaks
A: 

Try to use

{Binding Path=Header, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type FlowNode}}}.
Johnsonlu
You also need to add an `xmlns` for the namespace that `FlowNode` is defined in.
SLaks