WPF: binding to a dependency property

bindingwpf

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?

Best Answer

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.

Related Topic