wpf 绑定元素名究竟是如何工作的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18389118/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does binding elementname work exactly?
提问by James Joshua Street
I remember reading a couple of weeks ago that it sometimes doesn't work inside templates, and I recently tried to bind things in two different windows and it couldn't find the name declarations, so I assumed that it was local to the namespace of the class and just bound by setting the datacontext instead. However, I'm really curious when I am able to use binding elementname and when I cannot, because it's far more convenient when it is possible.
我记得几周前读到它有时在模板中不起作用,我最近尝试在两个不同的窗口中绑定东西,但找不到名称声明,所以我假设它是本地的命名空间类,只是通过设置数据上下文来绑定。但是,我真的很好奇什么时候可以使用 binding elementname ,什么时候不能,因为在可能的情况下它要方便得多。
edit: In reading that article, I found this to be interesting:
编辑:在阅读那篇文章时,我发现这很有趣:
"For this reason, styles and templates both define their own XAML namescopes, independent of whatever location in an object tree where the style or template is applied."
“出于这个原因,样式和模板都定义了自己的 XAML 名称范围,与应用样式或模板的对象树中的任何位置无关。”
if this is true, doesn't that mean that Binding ElementName should not work in templates at all? But then I definitely have some working bindings on ElementName within my templates. That is the most confusing part, why do some bindings randomly work inside the templates and others do not? It must have some method for trying to resolve the name even if it isn't in the template or same namescope
如果这是真的,那是不是意味着 Binding ElementName 根本不应该在模板中工作?但随后我肯定在我的模板中对 ElementName 有一些有效的绑定。这是最令人困惑的部分,为什么有些绑定会在模板中随机工作,而有些则不会?它必须有一些方法来尝试解析名称,即使它不在模板或相同的名称范围中
回答by H.B.
Basically you need to be in the same name scope(read this). Most UI elements are in the same tree sharing the same name scope, however there can be breaks and barriers (styles/templates) and if you have abstract objects like DataGridcolumns they do not have a name scope at all.
基本上你需要在相同的名称范围内(阅读这个)。大多数 UI 元素都在同一个树中,共享相同的名称范围,但是可能存在中断和障碍(样式/模板),如果您有像DataGrid列这样的抽象对象,它们根本没有名称范围。
I've been working with WPF long enough to guess when i'll run into problems and i know common areas but don't think there's an easy way to tell in all situations up-front.
我已经使用 WPF 工作了足够长的时间来猜测我何时会遇到问题并且我知道公共区域但不认为有一种简单的方法可以预先告诉所有情况。
if this is true, doesn't that mean that Binding ElementName should not work in templates at all? But then I definitely have some working bindings on ElementName within my templates.
如果这是真的,那是不是意味着 Binding ElementName 根本不应该在模板中工作?但随后我肯定在我的模板中对 ElementName 有一些有效的绑定。
Within is just fine, that is the same scope. The point here is that if you apply the template and they would not have their own scopes there would be conflicts.
内就好了,那是相同的范围。这里的重点是,如果您应用模板并且它们没有自己的作用域,则会发生冲突。
e.g.
例如
<Button/>
<Button/>
If we expand the ControlTemplateyou would get something like:
如果我们扩展ControlTemplate你会得到类似的东西:
<Border Name="bd" Background="{TemplateBinding Background}">...</Border>
<Border Name="bd" Background="{TemplateBinding Background}">...</Border>
Obviously we would get a name conflict.
显然,我们会遇到名称冲突。
Same for DataTemplatesin ItemsControls, if you name controls in the template that name would conflict with the same control instance in the applied template of other items.
与DataTemplatesin相同ItemsControls,如果您在模板中命名控件,该名称将与其他项目的应用模板中的相同控件实例冲突。
On another note, you can bind from inside a template to the outside because logically there can only be one instance with that name or you can give them a distinct precedence based on how "close" the name scope is, e.g.
另一方面,您可以从模板内部绑定到外部,因为逻辑上只能有一个具有该名称的实例,或者您可以根据名称范围的“接近”程度为它们指定不同的优先级,例如
<TextBox Name="tb" Text="Test"/>
<ItemsControl ItemsSource="ABC">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Text, ElementName=tb}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

