wpf 显示/隐藏 DataGrid 列 XAML

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30621672/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:10:54  来源:igfitidea点击:

Show/Hide DataGrid Columns XAML

wpfxamldatagrid

提问by EMAW2008

I am trying to build a DataGrid with controls that will allow a user to Show/Hide the columns. My DataGrid will have something like 40 columns, and not all may be necessary all of the time. I have been able to do this exact thing with a ListView that uses a GridView. Here is the code:

我正在尝试构建一个带有控件的 DataGrid,允许用户显示/隐藏列。我的 DataGrid 将有大约 40 列,并不是所有的时间都需要。我已经能够使用使用 GridView 的 ListView 来做这件事。这是代码:

<DataGrid Name="MyDataGrid" Grid.Row="2" Grid.Column="0" ItemsSource="{Binding ReportOrderingCustomersForSalesRepCollection}" Style="{DynamicResource styleDataGrid}" HeadersVisibility="All" AutoGenerateColumns="False" RowHeaderWidth="0" RowHeight="25">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Customer #" Binding="{Binding CustomerNumber}" Width="90" Visibility="{Binding ElementName=Visibility_Txt,Path=Text,Mode=OneWay}"/>
        <DataGridTextColumn Header="Customer Name" Binding="{Binding CustomerName}" Width="125" />
        <DataGridTemplateColumn Header="Email" CellTemplate="{StaticResource Email}" Width="150" />
    </DataGrid.Columns>
</DataGrid>
<!-- text box -->
<TextBox Name="Visiblility_Txt">
    <TextBox.Style>
        <Style TargetType="TextBox">
            <Style.Triggers>
                <DataTrigger Binding="{Binding ElementName=ColumnVisibilityCheck,Path=IsChecked}" Value="False">
                    <Setter Property="Text" Value="Collapsed" />
                </DataTrigger>
                <DataTrigger Binding="{Binding ElementName=ColumnVisibilityCheck,Path=IsChecked}" Value="True">
                    <Setter Property="Text" Value="Visible" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
</TextBox>
<!-- checkbox -->
<CheckBox Content="Show/Hide Customer Number" Name="ColumnVisibilityCheck" IsChecked="True" />

So I have a DataGrid setup. The Visibility Property on the first DataGridTextColumn is set as a binding to the text property of "Visibility_Txt". The text on that text box will be set to either Collapsed or Visible depending if the ColumnVisibilityCheck is checked or not.

所以我有一个 DataGrid 设置。第一个 DataGridTextColumn 上的 Visibility 属性被设置为“Visibility_Txt”的文本属性的绑定。该文本框上的文本将设置为 Collapsed 或 Visible,具体取决于 ColumnVisibilityCheck 是否被选中。

Like i said, this works with a listview, Why won't this work with a DataGrid?

就像我说的,这适用于列表视图,为什么不适用于 DataGrid?

回答by EMAW2008

Was able to find some more information on this. This link has a good answer/explanation. datagridtextcolumn-visibility-binding

能够找到更多关于此的信息。这个链接有一个很好的答案/解释。 数据网格文本列可见性绑定

It turns out that the columns of a DataGrid do not appear in the visual tree of a DataGrid.

事实证明,DataGrid 的列不会出现在 DataGrid 的可视化树中。

But the answer is to use x:reference in the visibility binding, and a BooleanToVisibilityConverter:

但答案是在可见性绑定中使用 x:reference 和一个 BooleanToVisibilityConverter:

            <DataGridTextColumn Header="Customer #" x:Name="CustNum_Col" Visibility="{Binding Source={x:Reference VisibilityCheck}, Path=IsChecked,Converter={StaticResource ObjectToVisibilityConverter}}" />

Visual Studio will show the squiggly line under the binding saying that "object not set to instance of an object" but it this still appears to work.

Visual Studio 将在绑定下显示波浪线,表示“对象未设置为对象的实例”,但这似乎仍然有效。

回答by MannyChalwe

Just set its MaxWidth property to Zero and it wont appear.

只需将其 MaxWidth 属性设置为零,它就不会出现。

DataGrid.Columns[IndexOfColumn].MaxWidth = 0;

回答by Saraf Talukder

1: Apply the following behaviour your DataGrid

1:应用以下行为你的DataGrid

<i:Interaction.Behaviors>
    <b:DataGridColumnVisibilityBindingBehavior Binding="{Binding IsNameVisible}" 
ColumnIndex="3" />
    </i:Interaction.Behaviors>

3: Here is the Implementation of the Behavior

3:这是行为的实现

public class DataGridColumnVisibilityBindingBehavior : Behavior<DataGrid>
{
    private static readonly DependencyProperty ProxyProperty = DependencyProperty.RegisterAttached(
        "Proxy",
        typeof(object),
        typeof(DataGridColumnVisibilityBindingBehavior),
        new PropertyMetadata(OnGridProxyChanged));

    private static readonly DependencyProperty AssociatedBinderProperty = DependencyProperty.RegisterAttached(
        "AssociatedBinder",
        typeof(ColumnDataContextBinder),
        typeof(DataGridColumnVisibilityBindingBehavior),
        new PropertyMetadata(default(ColumnDataContextBinder)));

    public Binding Binding { get; set; }

    public int ColumnIndex { get; set; }

    protected override void OnAttached()
    {
        base.OnAttached();

        CheckProxyBound();

        var column = AssociatedObject.Columns[this.ColumnIndex];
        var columnBinder = new ColumnDataContextBinder(column, this.Binding)
            {
                DataContext = AssociatedObject.GetValue(ProxyProperty)
            };

        column.SetValue(AssociatedBinderProperty, columnBinder);
    }

    private static void OnGridProxyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var grid = (DataGrid)d;
        foreach (var column in grid.Columns)
        {
            var binder = (ColumnBinder)column.GetValue(AssociatedBinderProperty);
            if (binder != null)
            {
                binder.DataContext = e.NewValue;
            }
        }
    }

    private void CheckProxyBound()
    {
        if (AssociatedObject.GetBindingExpression(ProxyProperty) == null)
        {
            AssociatedObject.SetBinding(ProxyProperty, new Binding());
        }
    }

    private sealed class ColumnDataContextBinder : FrameworkElement
    {
        private static readonly DependencyProperty IsVisibleProperty = DependencyProperty.Register(
            "IsVisible",
            typeof(bool),
            typeof(ColumnDataContextBinder),
            new PropertyMetadata(true, (s, e) => ((ColumnDataContextBinder)s).OnVisibilityChanged()));

        private readonly DataGridColumn column;

        public ColumnDataContextBinder(DataGridColumn column, Binding binding)
        {
            column = column;

            SetBinding(IsVisibleProperty, binding);
        }

        private bool IsVisible
        {
            get { return (bool)GetValue(IsVisibleProperty); }
        }

        private void OnVisibilityChanged()
        {
            column.Visibility = IsVisible ? Visibility.Visible : Visibility.Collapsed;
        }
    }
}

3: I hope this answers your question.

3:我希望这能回答你的问题。