属性Foo
位于我的DataContext
ViewModel {
Visibility Foo;
}
但我无法弄清楚如何在Foo
内访问Column
。在这种情况下,我假设它可能在Foo
DataGrid
ItemsSource
<DataGrid Visibility="{Binding Foo}"> // works
<DataGrid.Columns>
<DataGridTextColumn Visibility="{Binding Foo}" /> // fails
我试过了
Binding="{Binding DataContext.Foo}"
还有很多带有RelativeSource
标签的东西。
另外,有没有办法查看和选择要从GUI绑定的属性?
编辑:事实证明,Columns本身不是FrameworkElements,因此无法找到DataGrid祖先。但是,您可以使用下面的答案中的技术将Column的CellTemplate的属性绑定到DataContext。
答案 0 :(得分:5)
这应该有效:
<DataGridTextColumn Visibility="{Binding Path=DataContext.Foo, RelativeSource={RelativeSource AncestorType=DataGrid}}" />
您对当前项绑定的列是正确的 - 这就是您需要使用RelativeSource
获取DataGrid,然后访问其Foo
中的DataContext
属性的原因
至于选择要绑定的属性,有WPF设计器的属性面板和可视化工作室插件,如Resharper可以提供帮助,但最终他们在除了简单绑定之外的任何其他方面都做得不是很好,所以你是什么“留下来就是你自己和你对正在发生的事情的理解。”
答案 1 :(得分:2)
我在本文中找到了一些绑定在可视树之外的方法: Artificial Inheritance Contexts in WPF
我正在使用第四种选择(与他的建议有关)。它相当hacky但很简单。它有一个缺点,WPF设计师不喜欢它,并在设计时将错误记录在错误日志中。为了获得环境DataContext
,您可以使用x:Reference
标记扩展名绑定到可视树中当前XAML文件中的其他内容(请参阅msdn)。这与ElementName
绑定类似,不同之处在于它不依赖于InheritanceContext
,您通常不在可视树之外。如果FrameWorkElement
中没有其他内容可供参考,我只使用虚拟UserControl
。
我尝试仅引用包含UserControl
(或Window
或Page
等),但这会导致循环引用异常,因此我使用虚拟元素,直到有人显示我是一个更好的方式。
<FrameworkElement Name="dummyElement" />
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn
Visibility="{Binding Source={x:Reference dummyElement},
Path=DataContext.Foo}"
/>