[英]Bind datagrid column visibility MVVM
.Net 3.5 .Net 3.5
I know that the columns doesn't inherit the datacontext and by reading other posts i thought this would work: 我知道列不继承datacontext并通过阅读其他帖子我认为这将工作:
Visibility="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(FrameworkElement.DataContext).IsColumnNameVisible,
Converter={StaticResource boolToVisConverter}}"
However of course it doesn't.. The output window does not complain, it seems that the resource i found but the viewmodel property is newer called. 但是当然它没有..输出窗口没有抱怨,似乎我找到的资源但是viewmodel属性是更新的调用。
This is the entire DG : 这是整个DG:
<tk:DataGrid
VirtualizingStackPanel.IsVirtualizing="False"
Grid.Column="0"
AlternationCount="2"
AreRowDetailsFrozen="True"
AutoGenerateColumns="False"
Background="Transparent"
BorderThickness="0"
CanUserAddRows="False"
CanUserReorderColumns="True"
CanUserResizeRows="False"
GridLinesVisibility="None"
ItemsSource="{Binding Employees}"
SelectionMode="Single"
ColumnHeaderStyle="{StaticResource columnHeaderStyle}"
RowHeaderStyle="{StaticResource rowHeaderStyle}"
CellStyle="{StaticResource cellStyle}"
RowStyle="{StaticResource rowStyle}"
ContextMenu="{StaticResource columnHeaderContextMenu}">
<tk:DataGrid.Resources>
<ContextMenu x:Key="columnHeaderContextMenu" ItemsSource="{Binding ColumnHeaderContextMenuItems}" />
<Style TargetType="{x:Type ScrollBar}">
<Setter Property="Background" Value="Transparent"/>
</Style>
<Style TargetType="{x:Type tk:DataGridColumnHeader}">
<Setter Property="Background" Value="Transparent"/>
</Style>
</tk:DataGrid.Resources>
<tk:DataGrid.Triggers>
<EventTrigger RoutedEvent="tk:DataGridRow.MouseDoubleClick">
<EventTrigger.Actions>
<BeginStoryboard Storyboard="{StaticResource showDetailGrid}"/>
</EventTrigger.Actions>
</EventTrigger>
</tk:DataGrid.Triggers>
<tk:DataGrid.Columns>
<tk:DataGridTextColumn IsReadOnly="True" Header="test" Binding="{Binding Name, Mode=OneWay}" Visibility="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(FrameworkElement.DataContext).IsColumnNameVisible, Converter={StaticResource boolToVisConverter}}" />
</tk:DataGrid.Columns>
</tk:DataGrid>
I have read pretty much every single solution to this problem and nothing works.. 我几乎已经阅读了这个问题的每一个解决方案,没有任何作用..
DataGridColumn
s are not part of visual tree so they are not connected to the data context of the DataGrid
. DataGridColumn
不是可视树的一部分,因此它们不连接到DataGrid
的数据上下文。
For them to connect together use proxy element approach like this... 对于他们连接在一起使用像这样的代理元素方法...
FrameworkElement
in your ancestor panel's Resources
. Resources
添加代理FrameworkElement
。 ContentControl
bound to its Content
. Content
的不可见ContentControl
。 Use this ProxyElement
as StaticResource
for data context source in your visibility binding. 将此
ProxyElement
用作可见性绑定中的数据上下文源的StaticResource
。
<StackPanel> <StackPanel.Resources> <local:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> <FrameworkElement x:Key="ProxyElement" DataContext="{Binding}"/> </StackPanel.Resources> <ContentControl Visibility="Collapsed" Content="{StaticResource ProxyElement}"/> <DataGrid AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Visibility="{Binding DataContext.IsTextColumnVisibile, Source={StaticResource ProxyElement}, Converter={StaticResource BooleanToVisibilityConverter}}" Binding="{Binding Text}"/> </DataGrid.Columns> </DataGrid> </StackPanel>
Apart from DataGridColumn
, the above approach also works great to connect DataContext
to Popup
s and ContextMenu
s (ie any element that is not connected to the visual tree). 除了
DataGridColumn
之外,上述方法也非常适用于将DataContext
连接到Popup
和ContextMenu
(即任何未连接到可视树的元素)。
Silverlight Users Silverlight用户
Sadly setting contents of content controls with any framework elements is not allowed in silverlight. 遗憾的是,Silverlight中不允许使用任何框架元素设置内容控件的内容。 So the workaround would be (this is just a guidance code for silverlight) ...
所以解决方法是(这只是silverlight的指导代码)......
Change the framework element resource to something lightweight like a Textblock
. 将框架元素资源更改为像
Textblock
一样轻量级的东西。 (Silverlight does not allow specifying static resource of FrameworkElement
type.) (Silverlight不允许指定
FrameworkElement
类型的静态资源。)
<StackPanel.Resources> <TextBlock x:Key="MyTextBlock" />
Write an attached property to hold text block against the content control. 编写附加属性以保留对内容控件的文本块。
<ContentControl Visibility="Collapsed" local:MyAttachedBehavior.ProxyElement="{StaticResource MyTextBlock}" />
In the attached dependency property changed event handler, set the bind the data context of the content control to the text block's. 在附加的依赖项属性更改事件处理程序中,将内容控件的数据上下文绑定到文本块。
private static void OnProxyElementPropertyChanged( DependencyObject depObj, DependencyPropertyChangedEventArgs e) { if (depObj is ContentControl && e.NewValue is TextBlock) { var binding = new Binding("DataContext"); binding.Source = depObj; binding.Mode = OneWay; BindingOperations.SetBinding( (TextBlock)e.NewValue, TextBlock.DataContextProperty, binding); } }
So this way the textblock may not be connected to the visual tree but will probably be aware of the data context changes. 因此,文本块可能无法连接到可视树,但可能会知道数据上下文更改。
Hope this helps. 希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.