简体   繁体   English

绑定datagrid列可见性MVVM

[英]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... 对于他们连接在一起使用像这样的代理元素方法...

  1. Add a proxy FrameworkElement in your ancestor panel's Resources . 在祖先面板的Resources添加代理FrameworkElement
  2. Host it into an invisible ContentControl bound to its Content . 将其托管到绑定到其Content的不可见ContentControl
  3. 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连接到PopupContextMenu (即任何未连接到可视树的元素)。

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的指导代码)......

  1. 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" /> 
  2. Write an attached property to hold text block against the content control. 编写附加属性以保留对内容控件的文本块。

     <ContentControl Visibility="Collapsed" local:MyAttachedBehavior.ProxyElement="{StaticResource MyTextBlock}" /> 
  3. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM