Подтвердить что ты не робот

Есть ли способ скрыть определенный столбец в DataGrid, когда AutoGenerateColumns = True?

У меня есть DataGrid WPF 4.0, привязанный к DataTable с помощью AutoGenerateColumns = True. Столбцы являются динамическими, однако я знаю, что всегда будет столбец с именем ID, и я бы хотел скрыть этот столбец. Есть ли способ, которым я могу это сделать?

4b9b3361

Ответ 1

в вашем datagrid, подписаться на событие AutoGeneratingColumn, событие args (DataGridAutoGeneratingColumnEventArgs) имеет имя столбца и "Cancel", если имя столбца равно ID, а затем установить Cancel = true. должен сделать трюк.

Ответ 2

Вы можете использовать поведение (многоразовый код) для выполнения задания... Таким образом вы можете использовать атрибут, который будет централизовать видимость столбца в одном месте.

Применение:

<Window
...
 xmlns:extension="clr-namespace:WpfControlLibrary.Extension;assembly=WpfControlLibrary">

<DataGrid ...
    extension:DataGridBehavior.UseBrowsableAttributeOnColumn="True">

...

public class YourObjectItem
{
    [Browsable(false)]
        public Assembly Assembly { get; set; }

Код:

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace HQ.Wpf.Util.Behaviors
{
    /// <summary>
    /// Using this behavior on a dataGRid will ensure to display only columns with "Browsable Attributes"
    /// </summary>
    public static class DataGridBehavior
    {
        public static readonly DependencyProperty UseBrowsableAttributeOnColumnProperty =
            DependencyProperty.RegisterAttached("UseBrowsableAttributeOnColumn",
            typeof(bool),
            typeof(DataGridBehavior),
            new UIPropertyMetadata(false, UseBrowsableAttributeOnColumnChanged));

        public static bool GetUseBrowsableAttributeOnColumn(DependencyObject obj)
        {
            return (bool)obj.GetValue(UseBrowsableAttributeOnColumnProperty);
        }

        public static void SetUseBrowsableAttributeOnColumn(DependencyObject obj, bool val)
        {
            obj.SetValue(UseBrowsableAttributeOnColumnProperty, val);
        }

        private static void UseBrowsableAttributeOnColumnChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var dataGrid = obj as DataGrid;
            if (dataGrid != null)
            {
                if ((bool)e.NewValue)
                {
                    dataGrid.AutoGeneratingColumn += DataGridOnAutoGeneratingColumn;
                }
                else
                {
                    dataGrid.AutoGeneratingColumn -= DataGridOnAutoGeneratingColumn;
                }
            }
        }

        private static void DataGridOnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
        {
            var propDesc = e.PropertyDescriptor as PropertyDescriptor;

            if (propDesc != null)
            {
                foreach (Attribute att in propDesc.Attributes)
                {
                    var browsableAttribute = att as BrowsableAttribute;
                    if (browsableAttribute != null)
                    {
                        if (!browsableAttribute.Browsable)
                        {
                            e.Cancel = true;
                        }
                    }

                    // As proposed by "dba" stackoverflow user on webpage: 
                    // https://stackoverflow.com/questions/4000132/is-there-a-way-to-hide-a-specific-column-in-a-datagrid-when-autogeneratecolumns
                    // I added few next lines:
                    var displayName = att as DisplayNameAttribute;
                    if (displayName != null)
                    {
                        e.Column.Header = displayName.DisplayName;
                    }
                }
            }
        }
    }
}

Ответ 3

Другая возможность: Visibility.Collapsed:

    private void dataGrid_AutoGeneratingColumn(object sender, 
        DataGridAutoGeneratingColumnEventArgs e)
    {
        //Set properties on the columns during auto-generation 
        switch (e.Column.Header.ToString())
        {
            case "rownameYouWantToHide":
                e.Column.Visibility = Visibility.Collapsed;
                break;
        }
    }

Ответ 4

Я не могу говорить за 4, однако это было невозможно в 3.5 SP1, по крайней мере, без регистрации на событие, которое я хотел избежать любой ценой.

Вместо этого вы можете изменить код генерации на AutoGenerateColumns=False, а затем просто поместить нужные столбцы в XAML, поскольку базовые данные все равно будут помещены в столбцы соответствующим образом

            <dg:DataGridTextColumn Header="Display" Binding="{Binding DisplayName}"/>
            <dg:DataGridTextColumn Header="Host" Binding="{Binding HostName}"/>
            <dg:DataGridTextColumn Header="Database" Binding="{Binding Database}"/>
            <dg:DataGridTextColumn Header="Username" Binding="{Binding Username}"/>
            <dg:DataGridTextColumn Header="Password" Binding="{Binding Password}"/>

Это позволит вам отображать только те столбцы, которые вам нужны в отношении базовой модели, а также изменить Header для отображения по вашему усмотрению, поэтому вы не привязаны к имени Property на модели.

Ответ 5

Я бы не сказал, что это отличное решение... но... у вас может быть еще один слой абстракции например, скажем, у вас есть такой объект, как:

public class Foo
{
    public string Id { get; set; }

    public string Property2 { get; set; }

    public string Property3 { set; get; }
}

Вам не нужен столбец для Id, поэтому вы создаете новый объект

public class Foo2
{
    public string Property2 { get; set; }

    public string Property3 { set; get; }
}

тогда переведите/преобразуйте Foo в Foo2, и все готово.

Другим возможным способом (не всегда возможным) является изменение модификатора доступа до внутреннего

public class Foo
{
    internal string Id { get; set; }

    public string Property2 { get; set; }

    public string Property3 { set; get; }
}

таким образом вы не будете генерировать столбец Id.