WPF DataGrid - 使用CheckBox隐藏列

Rin*_*ind 8 wpf xaml wpfdatagrid

我试图使用复选框控制列的可见性(这是在WPF 4.0中).

这是我的XAML的片段:

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
</Window.Resources>

<CheckBox x:Name="GeneralDetailsVisible" Content="General Details"  Margin="5"/>

<DataGridTextColumn Header="Crew" 
  Binding="{Binding Path=Crew}" 
  Visibility="{Binding ElementName=GeneralDetailsVisible, 
                       Converter={StaticResource BoolToVisConverter}, 
                       Path=IsChecked}">
</DataGridTextColumn>
Run Code Online (Sandbox Code Playgroud)

现在我知道BooleanToVisibilityConverter转换器正在工作,因为我将它绑定到文本块,我可以看到我期望的值.如果我手动将值输入到列可见性属性中,则可以使用.但是当我绑定它时.我究竟做错了什么?

回答:

Quartermeister向我指出了答案.他指出的页面有点误导,因为帖子上列出的代码不起作用,你必须查看示例代码.

这是我最后的工作代码,适用于遇到此问题的任何人:

转换器将我们的ViewModels bool属性转换为我们的列属性的正确Visibility值.

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)

将复选框绑定到ViewModels属性,该属性将控制列visibiity.

<CheckBox
  x:Name="DetailsVisible" 
  Content="Show Details"
  IsChecked="{Binding Path=DisplayDetails}" />
Run Code Online (Sandbox Code Playgroud)

然后将Visibility绑定到ViewModels DisplayDetails属性.请注意,绑定到的列是自己的DataContext.

<DataGridTextColumn
  Header="Reliability" 
  Binding="{Binding Path=Reliability}" 
  Visibility="{Binding (FrameworkElement.DataContext).DisplayDetails, 
                       RelativeSource={x:Static RelativeSource.Self}, 
                       Converter={StaticResource BoolToVisConverter}}">
</DataGridTextColumn>
Run Code Online (Sandbox Code Playgroud)

将以下代码添加到项目中,这允许捕获DataGrids DataContext中的更改.

FrameworkElement.DataContextProperty.AddOwner(typeof(DataGridColumn));

FrameworkElement.DataContextProperty.OverrideMetadata(typeof(DataGrid),
        new FrameworkPropertyMetadata
           (null, FrameworkPropertyMetadataOptions.Inherits,
           new PropertyChangedCallback(OnDataContextChanged))); 
Run Code Online (Sandbox Code Playgroud)

然后,每当您更改DataGrids DataContext时,我们都会使用新的DataContext更新所有附加的DataGridColumsn.

public static void OnDataContextChanged(DependencyObject d,
                                        DependencyPropertyChangedEventArgs e)
{
    DataGrid grid = d as DataGrid;
    if (grid != null)
    {
        foreach (DataGridColumn col in grid.Columns)
        {
            col.SetValue(FrameworkElement.DataContextProperty, e.NewValue);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

一个值得关注的问题.如果您将DataContext添加到页面中,如下所示:

<Window.DataContext>
    <vm:WeaponListViewModel />
</Window.DataContext>
Run Code Online (Sandbox Code Playgroud)

然后在DataGrid有任何列之前调用上面的函数!

我在创建窗口后手动将我的DataConext附加到代码后面解决了这个问题.

tes*_*ern 6

IMO使用x:Namex:Reference并且Source是简单的:

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>

<CheckBox x:Name="showImperial" Content="Show Details" />

<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="TOV (Bls)" 
                    Width="80" 
                    Binding="{Binding TOVBarrels}"
                    Visibility="{Binding Source={x:Reference showImperial},
                                 Path=IsChecked, 
                                 Converter={StaticResource BooleanToVisibilityConverter}}"/>
</DataGrid.Columns>
</DataGrid>
Run Code Online (Sandbox Code Playgroud)

请参阅此答案:将 可见性绑定到可检查菜单项在 WPF 中显示错误“服务提供程序缺少 INameResolver 服务”


Qua*_*ter 3

问题在于 DataGrid 列不是可视化树的一部分,因此它们无法使用绑定。(“Binding”属性实际上是 Binding 类型的普通属性,而不是依赖属性。它将该绑定对象应用于单元格,这些单元格是可视化树的一部分。)

以下是博客的链接,该博客提供了解决方法,并演示了将列的可见性绑定到复选框:链接