WPF:绑定到依赖项属性

时间:2010-06-28 12:26:48

标签: wpf binding

我正在关注教程here。它显示了如何绑定到依赖项属性的基本示例。

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

其中“This”是当前窗口的名称:

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

每当我尝试做这样的事情时,我都会遇到同样的错误:

无法找到引用'ElementName = GridControlControl1'的绑定源。 BindingExpression:路径= ip地址;的DataItem = NULL; target元素是'TextBox'(Name ='AddressBox'); target属性为'Text'(类型'String')

我的代码:

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

代码隐藏:

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

它几乎就像.Net 4.0中发生了变化?

2 个答案:

答案 0 :(得分:6)

这取决于你想要什么。我会尝试提供一个完整的答案。使用这种语法保证更好成功的一种方法是使用VS2010的XAML Binding Builder,这就是我组装你将要看到的语法的方法。

如果你想让UserControl的一个元素显示你的IPAddress依赖属性,(看起来像是我正确定义的),请在UserControl标记的正文中使用这种语法:

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

大多数XAML绑定示例使用此语法而不是更详细的分层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>

...但两种语法都会产生相同的结果。 请注意,AncestorType是UserControl的类名,而不是在其他标记中使用UserControl时提供的x:Name

假设您在UserControl外部的标记中有一个UI元素,并且您希望访问该另一个控件的DependencyProperty 。标记看起来像这样:

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

或者,或者:

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

请注意,这次您使用的是GridControl的x:Name属性而不是类名,并且您将其称为ElementName,而不是“Ancestor” “。但在这两种情况下,Path都是您定义的DependencyProperty的声明名称。

答案 1 :(得分:3)

尝试使用RelativeSource:

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

而不是{x:Type UserControl}你可以在那里插入你的实际类型,即:

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