Domanda

In fase di esecuzione voglio creare dinamicamente colonne di griglia (o un altro layout di visualizzazione) in un ListView WPF. Non conosco prima il numero e i nomi delle colonne.

Voglio essere in grado di fare:
  MyListView.ItemSource = MyDataset;
  MyListView.CreateColumns ();

È stato utile?

Soluzione

Proverei il seguente approccio:

A) è necessario che la casella di riepilogo visualizzi la visualizzazione griglia - credo che tu l'abbia già fatto
B) definire uno stile per GridViewColumnHeader:

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

nel mio caso, avevo un sacco di altre proprietà impostate, ma nello scenario di base - avresti bisogno di Loaded event. Facendo clic: è utile se si desidera aggiungere funzionalità di ordinamento e filtro.

C) nel codice della visualizzazione elenco, associa il modello con la visualizzazione griglia:

    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) quindi nel tuo gestore OnHeaderLoaded, puoi impostare un modello corretto basato sui dati della colonna

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

// seleziona e applica qui il tuo modello di dati.

        e.Handled = true;
    }

E) Immagino che dovresti anche acquisire la proprietà della proprietà di dipendenza ItemsSource e gestirne l'evento modificato.

            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 stessa classe GridViewColumn non ha molte proprietà, quindi potresti voler aggiungere alcune informazioni lì usando le proprietà associate - cioè come un tag di colonna univoco - molto probabilmente l'intestazione verrà utilizzata per la localizzazione e non dovrai inoltrarla su questa .

In generale, questo approccio, anche se piuttosto complicato, ti permetterà di estendere facilmente la tua funzionalità di visualizzazione elenco.

Altri suggerimenti

È possibile aggiungere colonne in modo dinamico a un ListView utilizzando Proprietà collegate. Dai un'occhiata a questo articolo sul CodeProject , spiega esattamente che ...

WPF DynamicListView - Collegamento a una DataMatrix

Da 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);

Avere un DataTemplateselector per selezionare uno dei modelli predefiniti (dello stesso tipo di dati) e applicare il selettore a ListView. Puoi avere altrettanti DataTemplates con colonne diverse.

Puoi utilizzare un DataTemplateSelector per restituire un DataTemplate che hai creato dinamicamente nel codice. Tuttavia, questo è un po 'noioso e più complicato rispetto all'utilizzo di uno predefinito da XAML, ma è ancora possibile. Dai un'occhiata a questo esempio: http: //dedjo.blogspot .com / 2007/03 / creazione-DataTemplates-da-code.html

Per esperienza, posso consigliarti di evitare modelli di dati dinamici se puoi aiutarlo ... piuttosto usa i consigli qui forniti per creare esplicitamente le colonne ListView, piuttosto che provare a creare un DataTemplate dinamicamente.

Il motivo è che FrameworkElementFactory (o qualunque sia il nome della classe per la produzione di DataTemplates in fase di esecuzione) è un po 'confuso da usare (ed è deprecato a favore dell'uso di XAML per i modelli dinamici) - in entrambi i casi si ottiene un impatto sulle prestazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top