我记得几周前读到它有时在模板中不起作用,最近我试图在两个不同的窗口中绑定(bind)东西,但它找不到名称声明,所以我假设它是本地的类的命名空间,只是通过设置数据上下文来绑定(bind)。但是,我真的很好奇什么时候可以使用绑定(bind)元素名称,什么时候不能使用,因为如果可能,它会方便得多。
编辑:在阅读那篇文章时,我发现这很有趣:
“出于这个原因,样式和模板都定义了它们自己的 XAML 名称范围,独立于应用样式或模板的对象树中的任何位置。”
如果这是真的,那是否意味着 Binding ElementName 根本不应该在模板中工作?但是我肯定在我的模板中有一些关于 ElementName 的工作绑定(bind)。这是最令人困惑的部分,为什么一些绑定(bind)在模板中随机工作而其他的则不行?它必须有一些方法来尝试解析名称,即使它不在模板或相同的名称范围内也是如此
最佳答案
基本上你需要在同一个name scope (读这个)。大多数 UI 元素都在同一棵树中,共享相同的名称范围,但是可能存在中断和障碍(样式/模板),如果您有抽象对象,如 DataGrid
列,它们没有名称范围全部。
我使用 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.
Within 就好了,就是相同的作用域。这里的要点是,如果您应用模板,而它们没有自己的范围,就会发生冲突。
例如
<Button/>
<Button/>
如果我们展开ControlTemplate
,你会得到如下内容:
<Border Name="bd" Background="{TemplateBinding Background}">...</Border>
<Border Name="bd" Background="{TemplateBinding Background}">...</Border>
显然我们会遇到名称冲突。
对于 ItemsControls
中的 DataTemplates
也是如此,如果您在模板中命名控件,该名称将与其他项目应用的模板中的相同控件实例冲突。
另一方面,您可以从模板内部绑定(bind)到外部,因为逻辑上只能有一个具有该名称的实例,或者您可以根据名称范围的“接近”程度为它们赋予不同的优先级,例如
<TextBox Name="tb" Text="Test"/>
<ItemsControl ItemsSource="ABC">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Text, ElementName=tb}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
关于c# - 绑定(bind)元素名究竟是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18389118/