WPF: binding to dependency property

I follow the tutorial here . which shows a basic example of 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 is "Text" (type "String")

my code is:

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

separated code:

 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); } } 

has this almost changed something in .Net 4.0?

+4
source share
2 answers

It depends on what you want. I will try to give a complete answer. One way to guarantee better success with this syntax is to use the VS2010 XAML Binding Builder , this is how I put together the syntax you are about to see.

If you want the UserControl element to display your IPAddress dependency property (which looks like it is defined correctly for me), use this syntax in the UserControl markup body:

  <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 give the same results. Note that AncestorType is the class name of your UserControl, not x:Name , which you specify when using UserControl in a different markup.

Suppose you have a user interface element in the markup outside your UserControl, and you want to access your DependencyProperty for this 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 that this time you use the x:Name GridControl property, not the class name, and refer to it as an ElementName , not an Ancestor. In both cases, however, Path is the declared name of the DependencyProperty you define.

+6
source

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 can insert your actual type there, that is:

 <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> 
+3
source

Source: https://habr.com/ru/post/1314071/


All Articles