32 Stimmen

WPF: Wie man GridViewColumn mit XAML ausblenden?

Ich habe das folgende Objekt in App.xaml

<Application.Resources>
        <ResourceDictionary>
            <GridView x:Key="myGridView" x:Shared="false">
                             <GridViewColumn Header="Created" DisplayMemberBinding="{Binding Path=Created}"/>

... more code ...

Und ich verwende diese Gitteransicht an mehreren Stellen. Beispiel:

<ListView x:Name="detailList"   View="{StaticResource myGridView}" ...>

In einer der Verwendungen (wie detailList oben), möchte ich die Spalte Erstellt ausblenden, möglicherweise mit XAML?

Irgendwelche Ideen?

21voto

Ben McMillan Punkte 578

Ich finde, die einfachste Lösung ist die Verwendung von angehängten Eigenschaften:

public class GridViewColumnVisibilityManager
{       
    static void UpdateListView(ListView lv)
    {
        GridView gridview = lv.View as GridView;
        if (gridview == null || gridview.Columns == null) return;
        List<GridViewColumn> toRemove = new List<GridViewColumn>();
        foreach (GridViewColumn gc in gridview.Columns)
        {
            if (GetIsVisible(gc) == false)
            {
                toRemove.Add(gc);
            }
        }
        foreach (GridViewColumn gc in toRemove)
        {
            gridview.Columns.Remove(gc);
        }
    }

    public static bool GetIsVisible(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsVisibleProperty);
    }

    public static void SetIsVisible(DependencyObject obj, bool value)
    {
        obj.SetValue(IsVisibleProperty, value);
    }

    public static readonly DependencyProperty IsVisibleProperty =
        DependencyProperty.RegisterAttached("IsVisible", typeof(bool), typeof(GridViewColumnVisibilityManager), new UIPropertyMetadata(true));

    public static bool GetEnabled(DependencyObject obj)
    {
        return (bool)obj.GetValue(EnabledProperty);
    }

    public static void SetEnabled(DependencyObject obj, bool value)
    {
        obj.SetValue(EnabledProperty, value);
    }

    public static readonly DependencyProperty EnabledProperty =
        DependencyProperty.RegisterAttached("Enabled", typeof(bool), typeof(GridViewColumnVisibilityManager), new UIPropertyMetadata(false,
            new PropertyChangedCallback(OnEnabledChanged)));

        private static void OnEnabledChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        ListView view = obj as ListView;
        if (view != null)
        {
            bool enabled = (bool)e.NewValue;
            if (enabled)
            {
                view.Loaded += (sender, e2) =>
                {
                    UpdateListView((ListView)sender);
                };
                view.TargetUpdated += (sender, e2) =>
                {
                    UpdateListView((ListView)sender);
                };
                view.DataContextChanged += (sender, e2) =>
                {
                    UpdateListView((ListView)sender);
                };
            }
        }
    }
}

Dann kann es auch so verwendet werden:

<ListView foo:GridViewColumnVisibilityManager.Enabled="True">
...
<GridViewColumn Header="Status" foo:GridViewColumnVisibilityManager.IsVisible="{Binding ShowStatusColumn}">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate> ...

13voto

surfen Punkte 4604

Basiert auf der Antwort von Ben McMillan, unterstützt aber die dynamische Änderung der sichtbaren Eigenschaft. Ich habe seine Lösung weiter vereinfacht, indem ich die Eigenschaft IsEnabled entfernt habe.

public class GridViewColumnVisibilityManager
{
    static Dictionary<GridViewColumn, double> originalColumnWidths = new Dictionary<GridViewColumn, double>();

    public static bool GetIsVisible(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsVisibleProperty);
    }

    public static void SetIsVisible(DependencyObject obj, bool value)
    {
        obj.SetValue(IsVisibleProperty, value);
    }

    public static readonly DependencyProperty IsVisibleProperty =
        DependencyProperty.RegisterAttached("IsVisible", typeof(bool), typeof(GridViewColumnVisibilityManager), new UIPropertyMetadata(true, OnIsVisibleChanged));

    private static void OnIsVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        GridViewColumn gc = d as GridViewColumn;
        if (gc == null)
            return;

        if (GetIsVisible(gc) == false)
        {
            originalColumnWidths[gc] = gc.Width;
            gc.Width = 0;
        }
        else
        {
            if (gc.Width == 0)
                gc.Width = originalColumnWidths[gc];
        }
    }
}

6voto

Enrico Campidoglio Punkte 51948

Am besten ist es wahrscheinlich, eine benutzerdefiniertes Steuerelement durch Vererbung von der GridView Klasse, fügen die erforderlichen Spalten hinzu und stellen eine sinnvolle Eigenschaft zum Ein-/Ausblenden einer bestimmten Spalte bereit. Ihre benutzerdefinierte GridView-Klasse könnte wie folgt aussehen:

using System;
using System.Windows.Controls;

namespace MyProject.CustomControls
{
    public class CustomGridView : GridView
    {
        private GridViewColumn _fixedColumn;
        private GridViewColumn _optionalColumn;

        public CustomGridView()
        {
            this._fixedColumn = new GridViewColumn() { Header = "Fixed Column" };
            this._optionalColumn = new GridViewColumn() { Header = "Optional Column" };

            this.Columns.Add(_fixedColumn);
            this.Columns.Add(_optionalColumn);
        }

        public bool ShowOptionalColumn
        {
            get { return _optionalColumn.Width > 0; }
            set
            {
                // When 'False' hides the entire column
                // otherwise its width will be set to 'Auto'
                _optionalColumn.Width = (!value) ? 0 : Double.NaN;
            }
        }

    }
}

Dann können Sie diese Eigenschaft einfach von XAML aus festlegen, wie in diesem Beispiel:

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:cc="clr-namespace:MyProject.CustomControls"
        Title="Window1"
        Height="300"
        Width="300">
    <StackPanel>
        <ListView>
            <ListView.View>
                <cc:CustomGridView ShowOptionalColumn="False" />
            </ListView.View>
        </ListView>

        <ListView>
            <ListView.View>
                <cc:CustomGridView ShowOptionalColumn="True" />
            </ListView.View>
        </ListView>
    </StackPanel>
</Window>

Optional können Sie die ' CustomGridView.ShowOptionalColumn ' a DependencyProperty um es als verbindliches Ziel verwenden zu können.

4voto

Saber Punkte 2012

Entnommen aus aquí

<ListView Grid.Column="1" Grid.Row="1"  Name="FicheList" >
            <ListView.Resources>
                <ResourceDictionary>
                    <Style x:Key="hiddenStyle" TargetType="GridViewColumnHeader">
                        <Setter Property="Visibility" Value="Collapsed"/>
                    </Style>
                </ResourceDictionary>
            </ListView.Resources>
            <ListView.View>
                <GridView>
                    <GridViewColumn DisplayMemberBinding="{Binding Code}" Header="Code" Width="0" HeaderContainerStyle="{StaticResource hiddenStyle}" />
                    <GridViewColumn DisplayMemberBinding="{Binding FicheTitle}" Header="Title" Width="100" />
                    <GridViewColumn DisplayMemberBinding="{Binding CategoryName}" Header="Category" Width="100" />
                    <GridViewColumn DisplayMemberBinding="{Binding UpdateDate}" Header="Update Date" Width="100" />

                </GridView>
            </ListView.View>
        </ListView>

2voto

Jim Kniest Punkte 91

Ich habe eine viel einfachere Lösung als die Verwendung eines Attached Behavior.

Alles, was Sie tun müssen, ist die Eigenschaft Width der GridViewColumn mit einem Boolean in Ihrem ViewModel zu verbinden. Dann erstellen Sie einen einfachen Konverter wie BooleanToWidthConverter, der einen Boolean nimmt und einen Double zurückgibt, Null, wenn es falsch ist, x Breite, wenn es wahr ist.

Ich hoffe, dies hilft Ihnen und macht Ihnen das Leben leichter.

XAML:

<GridViewColumn x:Name="MyHiddenGridViewColumn"
                Width={Binding Path=IsColumnVisibleProperty, Converter={StaticResource BooleanToWidthConverter}}">
   <!-- GridViewColumn.HeaderTemplate etc. goes here. -->
</GridViewColumn>

Konverter:

public class BooleanToWidthConverter : IValueConverter
    {
        private const double Column_Width = 40.0;

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null && value != DependencyProperty.UnsetValue)
            {
                bool isVisible = (bool) value;

                return isVisible ? Column_Width : 0;
            }
            return Column_Width;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X