WPF:绑定到依赖属性

Posted

技术标签:

【中文标题】WPF:绑定到依赖属性【英文标题】:WPF: binding to a dependency property 【发布时间】:2011-03-09 02:53:45 【问题描述】:

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

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

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

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

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

找不到与引用“ElementName=GridControlControl1”进行绑定的源。绑定表达式:路径=IP地址;数据项=空;目标元素是“文本框”(名称=“地址框”);目标属性是“文本”(类型“字符串”)

我的代码:

 <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 中的某些变化?

【问题讨论】:

我只是复制了你所做的同样的事情,我似乎没有得到任何错误。 你用的是什么框架? 好的,感谢您确认这是可行的。我的设置一定有问题。 【参考方案1】:

这取决于你想要什么。我会尽力提供一个完整的答案。保证使用此语法取得更大成功的一种方法是使用 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,而不是“祖先”。 em> 不过,在这两种情况下,Path 是您定义的 DependencyProperty 的声明名称。

【讨论】:

谢谢。虽然我和安德烈亚斯已经做过同样的事情,但我很欣赏你的帖子和 xaml 构建器链接。 不客气。绑定语法很难;在我看来,它只会在运行时进行评估,并且几乎无法解释错误。除了我的一般答案之外,我能想到的唯一一件事是Path=IPAddress 之后缺少一个右括号字符,但 XAML 编辑器会立即捕捉到这一点......那个,我使用“FrameworkPropertyMetadata”而不是而不是“UIPropertyMetadata”来设置DP,但我认为这也没有区别。 这个答案对我很有帮助。谢谢。【参考方案2】:

尝试使用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>

【讨论】:

谢谢,在诉诸 DependecyProperty 方法之前,我实际上已经尝试了 FindAncestor 的所有可能迭代......绝对是 x:Type CustomControl 那现在可以用了吗?还是 FindAncestor 方法有什么问题? 在 FindAncestor 上没有运气。我在星期五用这种方法浪费了几个小时。尝试将其添加到顶部窗口以及 Control,将其引用为 x:Type .. 不断收到相同的非信息性错误消息.. “无法找到祖先等等” 等我在家的时候我会尝试重现。在这里,我没有合适的 IDE(甚至时间)来进行测试。我们真的应该能够做到这一点...... :) 不要放弃! 我不能放弃!必须以某种方式完成我的项目:)

以上是关于WPF:绑定到依赖属性的主要内容,如果未能解决你的问题,请参考以下文章

具有依赖属性绑定到 DockPanel.Dock 附加属性的 WPF 自定义控件不起作用

2019-11-29-WPF-依赖属性绑定不上调试方法

WPF:将静态资源绑定到用户控件中的依赖项属性

WPF 10天修炼 第十天- WPF数据绑定

如何让我的 WPF 用户控件的依赖属性更新我的视图模型?

WPF教程:依赖属性