AlexanderVanDam
AlexanderVanDam

Reputation: 45

WPF: Binding a property to a Custom UserControl

I have the following problem in wpf:

I have defined a user control (in namespace test) containing a textbox (and several other controls, only show the relevant parts of the xaml):

<UserControl (...)
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    name="Spinbox">
    (...)
    <StackPanel Orientation="Horizontal">
    <TextBox x:Name="tbText" (...)>
        <TextBox.Text>
            <Binding Path="Value" UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <local:ValidateValue MinVal="0" MaxVal="1" />
                </Binding.ValidationRules>
                <Binding.NotifyOnValidationError>true</Binding.NotifyOnValidationError>
            </Binding>
        </TextBox.Text>
    </TextBox>
    (...)

In the main window file, I am using this spinbox:

<Test:SpinBox x:Name="tbTestSpinbox" Value="{Binding Path=TheValue}" 
              MinValue="0" MaxValue="150">
    <Test:SpinBox.Behavior>
        <Controls:SpinBoxNormalBehavior />
    </Test:SpinBox.Behavior>
</Test:SpinBox>

In the code behind, I have defined TheValue:

private double theValue;

public Window1()
{
  InitializeComponent();
  TheValue = 10;
}


public double TheValue
{
  get { return theValue; }
  set
  {
    theValue = value;
    NotifyPropertyChanged("TheValue");
  }
}

/// <summary>
/// Occurs when a property value changes
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;

protected void NotifyPropertyChanged(String info)
{
  if (PropertyChanged != null)
  {
    PropertyChanged(this, new PropertyChangedEventArgs(info));
  }
}

When I try run this application, I get the message in the output window:

System.Windows.Data Error: 39 : BindingExpression path error: 'TheValue' property not found on 'object' ''SpinBox' (Name='tbTestSpinbox')'. BindingExpression:Path=TheValue; DataItem='SpinBox' (Name='tbTestSpinbox'); target element is 'SpinBox' (Name='tbTestSpinbox'); target property is 'Value' (type 'Double')

And the spinbox is not filled with the value 10, but the default 0.

Does anyone have an idea how to make sure that the value is correctly shown?

Upvotes: 2

Views: 4735

Answers (2)

Thomas Levesque
Thomas Levesque

Reputation: 292495

Unless specified otherwise, the binding path is always relative to the DataContext. So in your window's constructor, you should add that instruction :

this.DataContext = this;

Upvotes: 1

Matt Hamilton
Matt Hamilton

Reputation: 204209

You're setting the UserControl's DataContext to itself in its XAML:

<UserControl (...)
    DataContext="{Binding RelativeSource={RelativeSource Self}}"

... so later when you say this:

<Test:SpinBox x:Name="tbTestSpinbox" Value="{Binding Path=TheValue}"
           MinValue="0" MaxValue="150">

the "Value" binding is looking for a "TheValue" property on the SpinBox itself.

Instead of using DataContext, change your bindings inside the UserControl to bind back to the control itself. I usually do that by giving the entire UserControl a XAML name:

<UserControl x:Name="me">

and then using an element binding:

<TextBox.Text>
    <Binding Path="Value"
             ElementName="me"
             UpdateSourceTrigger="PropertyChanged">

Upvotes: 9

Related Questions