我创建了一个UserControl
我想使用如下代码:
<controls:ColorWithText Color="Red" Text="Red color" />
到目前为止,我已经实现了类似的控件,如下所示:
<UserControl x:Class="Namespace.ColorWithText" Name="ThisControl">
<StackPanel Orientation="Horizontal" >
<Border Width="15" Height="15" Background="{Binding Color, ElementName=ThisControl}" />
<TextBlock Text="{Binding Text, ElementName=ThisControl}" />
</StackPanel>
</UserControl>
其中Color
和Text
是代码中定义的控件的依赖属性。这是可行的,但似乎没有必要每次都指定ElementName
。
另一个可行的方法是使用
<UserControl x:Class=… DataContext="{Binding ElementName=ThisControl}" Name="ThisControl">
并且不指定ElementName
s,但对我来说,这似乎也不是一个干净的解决方案。
我有两个问题:
1.为什么<UserControl DataContext="{RelativeSource Self}">
不起作用?
1.做这种事情的最好方法是什么?
6条答案
按热度按时间1bqhqjot1#
对于第一个,请尝试:
对于第二个问题,我认为使用
ElementName
或AncestorBinding
是绑定到UserControl
属性的最佳方式。balp4ylt2#
为什么不能使用
<UserControl DataContext="{RelativeSource Self}">
?这是您使用控件的方式
现在,因为我们已经在控件中硬编码了数据上下文,它将改为尝试在ColorWithText对象上查找ColorToUse属性,而不是在ViewModel上查找,这显然会失败。
这就是为什么不能在用户控件上设置DataContext。感谢Brandur让我明白了这一点。
执行此类操作的最佳方法是什么?
您应该改为在控件的第一个子UI项目中设定DataContext。
在你的情况下你想要
现在,您有了一个引用控件的DataContext,因此可以使用相对绑定访问该控件的任何属性。
2lpgd9683#
I know this has been answered but none of the explanations give an Understanding of
DataContext
and how it works. This link does a great job for that.EVERYTHING YOU WANTED TO KNOW ABOUT DATABINDING IN WPF, SILVERLIGHT AND WP7 (PART TWO)
In answer to your question #1
Why doesn't
<UserControl DataContext="{RelativeSource Self}">
work?This is a summary of the above link.
DataContext
should not be set to Self atUserControl
Element level. This is because it breaks the Inheritance of theDataContext
. If you do set it to self and you place this control on a Window or another control, it will not inherit the WindowsDataContext
.DataContext
is inherited to all lower Elements of the XAML and to all the XAML ofUserControl
s unless it is overwritten somewhere. By setting theUserControl
DataContext
to itself, this overwrites theDataContext
and breaks Inheritance. Instead, nest it one Element deep in the XAML, in your case, theStackPanel
. Put theDataContext
binding here and bind it to theUserControl
. This preserves the Inheritance.See also this link below for a detailed explanation of this.
A SIMPLE PATTERN FOR CREATING RE-USEABLE USERCONTROLS IN WPF / SILVERLIGHT
In answer to your question #2 What is the best way to do something like this?
See code example below.
Note that once you do this, you will not need the
ElementName
on each binding.w8biq8rn4#
你应该用
有关数据绑定的疑问,请始终参阅此页。
http://www.nbdtech.com/Blog/archive/2009/02/02/wpf-xaml-data-binding-cheat-sheet.aspx
vwkv1x7d5#
可以在构造函数本身将datacontext设置为self。
现在你可以简单地说
vc9ivgsu6#
对于那些绝望的灵魂,他们试图让pdross的答案起作用,但却不能:
它缺少了一个重要的细节-
Path=DataContext
。当您将其添加到下面的代码段时,它开始工作,结果如下: