简体   繁体   中英

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?

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">

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM