web-dev-qa-db-ja.com

AutoGenerateColumns = Trueの場合にDataGridの特定の列を非表示にする方法はありますか?

AutoGenerateColumns = Trueを使用してDataTableにバインドされているWPF4.0DataGridがあります。列は動的ですが、IDという名前の列が常に存在することはわかっているので、この列を非表示にします。これを行う方法はありますか?

29
Rachel

データグリッドで、AutoGeneratingColumnイベントをサブスクライブします。イベントargsDataGridAutoGeneratingColumnEventArgs)には列名があり、列名の場合は「Cancel」があります。 IDである場合はCancel = true。トリックを行う必要があります。

34
Alex Lo

ビヘイビアー(再利用可能なコード)を使用してジョブを実行できます...このようにして、列の可視性を1か所に集中させる属性を使用できます。

使用法:

<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;
                    }
                }
            }
        }
    }
}
10
Eric Ouellet

他の可能性は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;
        }
    }
5
Boern

私はそれが素晴らしい解決策だとは言いません...しかし...あなたはもう1つの抽象化レイヤーを持つことができます例えばあなたが次のようなオブジェクトを持っているとしましょう:

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列も生成されません。

0
Kapitán Mlíko

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名に縛られることはありません。モデルに。

0
Aaron McIver