5

I am following a tutorial here. which shows a basic example on how to bind to a dependency property.

<Binding ElementName="This" Path="IPAddress" UpdateSourceTrigger="PropertyChanged"> 

where "This" is the name of the current window:

<Window x:Class="SOTCBindingValidation.Window1" x:Name="This" 

whenever i try to do something like this, i keep getting the same error:

Cannot find source for binding with reference 'ElementName=GridControlControl1'. BindingExpression:Path=IPAddress; DataItem=null; target element is 'TextBox' (Name='AddressBox'); target property is 'Text' (type 'String')

my code:

 <UserControl x:Class="WpfGridtest.GridControl" x:Name="GridControlControl1" ... /> <TextBox x:Name="AddressBox"> <TextBox.Text> <Binding ElementName="GridControlControl1" Path="IPAddress" UpdateSourceTrigger="PropertyChanged"> </Binding> </TextBox.Text> </TextBox> 

codebehind:

partial class GridControl : UserControl public static readonly DependencyProperty IPAddressProperty = DependencyProperty.Register("IPAddress", typeof(string), typeof(GridControl), new UIPropertyMetadata("1.1.1.1")); public string IPAddress { get { return (string)GetValue(IPAddressProperty); } set { SetValue(IPAddressProperty, value); } } 

it's almost like something changed in .Net 4.0?

3
  • i just repro the same thing what you have done, i did't seem to get any error. Commented Jun 28, 2010 at 13:00
  • what framework are you using ? Commented Jun 28, 2010 at 13:21
  • ok, thanks for conforming that this works.. something must be wrong with my setup. Commented Jun 28, 2010 at 15:36

2 Answers 2

8

It depends on what you want. I'll try to offer a complete answer. One way to guarantee better success with this syntax is to use VS2010's XAML Binding Builder, which is how I assembled the syntax you're about to see.

If you want an element of the UserControl to display your IPAddress dependency property, (which looks like it's defined correctly to me), use this syntax within the body of the UserControl's markup:

 <TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type my:GridControl}, AncestorLevel=1}, Path=IPAddress}" /> 

Most XAML binding examples use this syntax rather than the more verbose hierarchical XML:

 <TextBlock> <TextBlock.Text> <Binding Path="IPAddress"> <Binding.RelativeSource> <RelativeSource Mode="FindAncestor" AncestorType="{x:Type my:GridControl}" AncestorLevel="1" /> </Binding.RelativeSource> </Binding> </TextBlock.Text> </TextBlock> 

...but both kinds of syntax produce the same results. Note here that the AncestorType is the class name of your UserControl, not the x:Name you would supply when using the UserControl in other markup.

Suppose you have a UI element in markup outside your UserControl, and you want access to your DependencyProperty for that other control. The markup looks something like this:

 <my:GridControl x:Name="GridControl1" IPAddress="192.168.1.1" /> <TextBox Text="{Binding ElementName=GridControl1, Path=IPAddress}"/> 

Or, alternatively, this:

 <TextBox> <TextBox.Text> <Binding ElementName="GridControl1" Path="IPAddress"/> </TextBox.Text> </TextBox> 

Note here that this time you're using the x:Name property of the GridControl rather than the class name, and that you refer to it as an ElementName, and not an "Ancestor". In both cases, though, the Path is the declared name of the DependencyProperty you defined.

Sign up to request clarification or add additional context in comments.

2 Comments

thank you. although it is the same thing me and Andreas have already, but i appreciate your post, and xaml builder link.
You're welcome. Binding syntax is tough; it only gets evaluated at runtime and the errors are nearly impossible to interpret, in my opinion. About the only thing I can think of other than my general answer is that there is a missing right-bracket character after Path=IPAddress, but the XAML editor would have caught that right away... That, and I used "FrameworkPropertyMetadata" rather than "UIPropertyMetadata" to set up the DP, but I don't think that's a difference with a distinction either.
3

Try using RelativeSource:

<TextBox> <TextBox.Text> <Binding Path="IPAddress"> <Binding.RelativeSource> <RelativeSource Mode="FindAncestor" AncestorType="{x:Type UserControl}" AncestorLevel="1" /> </Binding.RelativeSource> </Binding> </TextBox.Text> </TextBox> 

Instead of {x:Type UserControl}you could insert your actual type there, i.e.:

<TextBox> <TextBox.Text> <Binding Path="IPAddress"> <Binding.RelativeSource> <RelativeSource xmlns:my="clr-namespace:WpfGridtest" Mode="FindAncestor" AncestorType="{x:Type my:GridControl}" AncestorLevel="1" /> </Binding.RelativeSource> </Binding> </TextBox.Text> </TextBox> 

6 Comments

thanks, i've actually tried seemingly every possible iteration of FindAncestor before resorting to DependecyProperty approach.. definitely x:Type CustomControl
Did it work now then? Or is there anything wrong with the FindAncestor approach?
had no luck with FindAncestor. i wasted hours on friday with that approach. tried adding it to the top Window, as well as Control, referencing it as x:Type .. keep getting the same non informative error messages.. "unable to find ancestor blah blah"
When I'm at home later I will try to reproduce. Here I don't have an appropriate IDE (and even time) for testing. We should really be able to accomplish this... :) do not give up!
i can't give up! have to finish my project somehow :)
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.