Question

Au moment de l'exécution, je souhaite créer de manière dynamique des colonnes de grille (ou une autre présentation d'affichage) dans un ListView WPF. Je ne connais pas le nombre et les noms des colonnes à l'avance.

Je veux pouvoir faire:
  MyListView.ItemSource = MyDataset;
  MyListView.CreateColumns ();

Était-ce utile?

La solution

je voudrais essayer l'approche suivante:

A) vous devez avoir l'affichage de la grille dans la liste déroulante - je crois que vous l'avez déjà fait
B) définir un style pour GridViewColumnHeader:

        <Style TargetType="{x:Type GridViewColumnHeader}" x:Key="gridViewColumnStyle">
            <EventSetter Event="Click" Handler="OnHeaderClicked"/>
            <EventSetter Event="Loaded" Handler="OnHeaderLoaded"/>
        </Style>

Dans mon cas, j’avais plein d’autres propriétés, mais dans le scénario de base, vous auriez besoin d’un événement Loaded. Cliqué - utile si vous souhaitez ajouter une fonctionnalité de tri et de filtrage.

C) dans votre code listview, liez le modèle à votre gridview:

    public MyListView()
    {
        InitializeComponent();
        GridView gridViewHeader = this.listView.View as GridView;
        System.Diagnostics.Debug.Assert(gridViewHeader != null, "Expected ListView.View should be GridView");
        if (null != gridViewHeader)
        {
            gridViewHeader.ColumnHeaderContainerStyle = (Style)this.FindResource("gridViewColumnStyle");
        }
    }

D) puis dans votre gestionnaire OnHeaderLoaded, vous pouvez définir un modèle approprié en fonction des données de la colonne

    void OnHeaderLoaded(object sender, RoutedEventArgs e)
    {
        GridViewColumnHeader header = (GridViewColumnHeader)sender;
        GridViewColumn column = header.Column;

// sélectionnez et appliquez votre modèle de données ici.

        e.Handled = true;
    }

E) Je suppose que vous devez également acquérir la propriété de la propriété de dépendance ItemsSource et gérer son événement modifié.

            ListView.ItemsSourceProperty.AddOwner(typeof(MyListView), new PropertyMetadata(OnItemsSourceChanged));

        static void OnItemsSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            MyListView view = (MyListView)sender;
            //do reflection to get column names and types
            //and for each column, add it to your grid view:
            GridViewColumn column = new GridViewColumn();
            //set column properties here...
            view.Columns.Add(column);
        }

la classe GridViewColumn elle-même n'a pas beaucoup de propriétés, vous pouvez donc y ajouter des informations en utilisant des propriétés attachées - c'est-à-dire comme une balise de colonne unique - l'en-tête sera probablement utilisé pour la localisation, et vous ne ferez pas de relais avec celle-ci. .

En général, cette approche, même si elle est assez compliquée, vous permettra d’étendre facilement la fonctionnalité d’affichage de liste.

Autres conseils

Vous pouvez ajouter des colonnes de manière dynamique à un ListView en utilisant Propriétés attachées. Découvrez cet article sur le CodeProject , il explique exactement que ...

WPF DynamicListView - Liaison à un DataMatrix

À partir de MSDN:

    MyListBox.ItemsSource = view;
    ListView myListView = new ListView();

    GridView myGridView = new GridView();
    myGridView.AllowsColumnReorder = true;
    myGridView.ColumnHeaderToolTip = "Employee Information";

    GridViewColumn gvc1 = new GridViewColumn();
    gvc1.DisplayMemberBinding = new Binding("FirstName");
    gvc1.Header = "FirstName";
    gvc1.Width = 100;
    myGridView.Columns.Add(gvc1);
    GridViewColumn gvc2 = new GridViewColumn();
    gvc2.DisplayMemberBinding = new Binding("LastName");
    gvc2.Header = "Last Name";
    gvc2.Width = 100;
    myGridView.Columns.Add(gvc2);
    GridViewColumn gvc3 = new GridViewColumn();
    gvc3.DisplayMemberBinding = new Binding("EmployeeNumber");
    gvc3.Header = "Employee No.";
    gvc3.Width = 100;
    myGridView.Columns.Add(gvc3);

    //ItemsSource is ObservableCollection of EmployeeInfo objects
    myListView.ItemsSource = new myEmployees();
    myListView.View = myGridView;
    myStackPanel.Children.Add(myListView);

Disposez d'un sélecteur de modèles de données pour sélectionner l'un des modèles prédéfinis (Du même type de données) et appliquez le sélecteur à la vue liste. Vous pouvez avoir autant de DataTemplates avec des colonnes différentes.

Vous pouvez utiliser un DataTemplateSelector pour renvoyer un DataTemplate que vous avez créé de manière dynamique dans le code. Cependant, ceci est un peu fastidieux et plus compliqué que d’utiliser un fichier prédéfini de XAML, mais cela reste possible. Regardez cet exemple: http: //dedjo.blogspot .com / 2007/03 / creation-datatemplates-from-code.html

Par expérience, je peux vous recommander d’éviter les modèles de données dynamiques si vous pouvez l’aider ... utilisez plutôt les conseils donnés ici pour créer explicitement les colonnes ListView, plutôt que d’essayer de créer un DataTemplate de manière dynamique.

La raison en est que FrameworkElementFactory (ou quel que soit le nom de la classe utilisé pour la production de DataTemplates au moment de l'exécution) est un peu fastidieux à utiliser (et est déconseillé en faveur de l'utilisation de XAML pour des modèles dynamiques), quelle que soit la solution choisie. / p>

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top