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:绑定到依赖属性的主要内容,如果未能解决你的问题,请参考以下文章