XAML 绑定数据网格列可见性MVVM

2vuwiymt  于 2022-12-25  发布在  其他
关注(0)|答案(1)|浏览(126)

.网络3.5
我知道专栏不会继承datacontext,通过阅读其他帖子,我认为这会起作用:

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

然而,当然它没有..输出窗口没有抱怨,它似乎是我找到的资源,但viewmodel属性是较新的调用.
这是整个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>

我已经读了几乎每一个解决这个问题的方法,没有一个工作。

gt0wga4j

gt0wga4j1#

DataGridColumn不是可视化树的一部分,因此它们未连接到DataGrid的数据上下文。
要将它们连接在一起,请使用代理元素方法,如下所示...
1.在祖先面板的Resources中添加一个代理FrameworkElement
1.将其托管到绑定到其Content的不可见ContentControl中。
1.将此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>

除了DataGridColumn之外,上述方法也适用于将DataContext连接到Popup s和ContextMenu s(即未连接到可视树的任何元素)。

Silverlight用户

遗憾的是,在silverlight中不允许使用任何框架元素设置内容控件的内容。因此,解决方法是(这只是silverlight的一个指导代码)...
1.将框架元素资源更改为Textblock等轻量级资源。(Silverlight不允许指定FrameworkElement类型的静态资源。)

<StackPanel.Resources>
     <TextBlock x:Key="MyTextBlock" />

1.编写一个附加属性以根据内容控件保存文本块。

<ContentControl Visibility="Collapsed" 
                 local:MyAttachedBehavior.ProxyElement="{StaticResource MyTextBlock}" />

1.在附加的依赖项属性已更改事件处理程序中,设置将内容控件的数据上下文绑定到文本块的。

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);
        }
  }

因此,通过这种方式,文本块可能不会连接到可视树,但可能知道数据上下文的更改。

相关问题