绑定数据网格列可见性 MVVM [英] Bind datagrid column visibility MVVM

查看:37
本文介绍了绑定数据网格列可见性 MVVM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

.Net 3.5

我知道列不继承数据上下文,通过阅读其他帖子,我认为这会起作用:

I know that the columns doesn't inherit the datacontext and by reading other posts i thought this would work:

Visibility="{Binding RelativeSource={x:Static RelativeSource.Self},
                     Path=(FrameworkElement.DataContext).IsColumnNameVisible,
                     Converter={StaticResource boolToVisConverter}}"

当然不是..输出窗口没有抱怨,似乎是我找到的资源但 viewmodel 属性被更新了.

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.

这是整个 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 不是可视化树的一部分,因此它们不连接到 DataGrid.

DataGridColumns are not part of visual tree so they are not connected to the data context of the DataGrid.

为了让他们连接一起使用这样的代理元素方法......

For them to connect together use proxy element approach like this...

  1. 在祖先面板的Resources中添加一个代理FrameworkElement.
  2. 将其托管到与其 Content 绑定的不可见 ContentControl 中.
  3. 将此 ProxyElement 用作可见性绑定中数据上下文源的 StaticResource.

  1. Add a proxy FrameworkElement in your ancestor panel's Resources.
  2. Host it into an invisible ContentControl bound to its Content.
  3. Use this ProxyElement as StaticResource for data context source in your visibility binding.

<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> 

除了DataGridColumn,上述方法也可以很好地将DataContext 连接到Popups 和ContextMenus(即任何未连接到可视化树的元素).

Apart from DataGridColumn, the above approach also works great to connect DataContext to Popups and ContextMenus (i.e. any element that is not connected to the visual tree).

Silverlight 用户

遗憾的是,在 Silverlight 中不允许使用任何框架元素设置内容控件的内容.所以解决方法是(这只是 Silverlight 的指导代码)...

Sadly setting contents of content controls with any framework elements is not allowed in silverlight. So the workaround would be (this is just a guidance code for silverlight) ...

  1. 将框架元素资源更改为诸如 Textblock 之类的轻量级资源.(Silverlight 不允许指定 FrameworkElement 类型的静态资源.)

  1. Change the framework element resource to something lightweight like a Textblock. (Silverlight does not allow specifying static resource of FrameworkElement type.)

<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.

    希望这会有所帮助.

    这篇关于绑定数据网格列可见性 MVVM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆