Virtualizzare un ItemsControl?

Ho un ItemsControl contenente un elenco di dati che vorrei virtualizzare, tuttavia VirtualizingStackPanel.IsVirtualizing="True" non sembra funzionare con ItemsControl .

È davvero così o esiste un altro modo per farlo che non conosco?

Per testare ho utilizzato il seguente blocco di codice:

        

Se cambio ItemsControl in un ListBox , posso vedere che l’evento Initialized viene eseguito solo una manciata di volte (gli enormi margini sono solo così devo solo passare attraverso alcuni record), tuttavia come ItemsControl ogni elemento viene inizializzato.

Ho provato a impostare ItemsControlPanelTemplate su VirtualizingStackPanel ma ciò non sembra essere di aiuto.

In realtà c’è molto di più rispetto al semplice uso di ItemsPanelTemplate utilizza VirtualizingStackPanel . Il ControlTemplate predefinito per ItemsControl non ha un ScrollViewer , che è la chiave per la virtualizzazione. L’aggiunta al modello di controllo predefinito per ItemsControl (utilizzando il modello di controllo per ListBox come modello) ci fornisce quanto segue:

                      

(A proposito, un ottimo strumento per guardare i modelli di controllo di default è Show Me The Template )

Cose da notare:

Devi impostare ScrollViewer.CanContentScroll="True" , vedi qui per il motivo.

Notare anche che ho messo VirtualizingStackPanel.VirtualizationMode="Recycling" . Ciò ridurrà il numero di volte in cui TextBlock_Initialized è chiamato a molti TextBlocks visibili sullo schermo. Puoi leggere di più sulla virtualizzazione dell’interfaccia utente qui .

EDIT: dimenticato di dichiarare l’ovvio: come soluzione alternativa, è sufficiente sostituire ItemsControl con ListBox 🙂 Inoltre, controlla questa pagina Ottimizzazione delle prestazioni su MSDN e nota che ItemsControl non si trova nella tabella “Controlli che implementa le prestazioni”, ecco perché dobbiamo modificare il modello di controllo.

Basandosi sulla risposta di DavidN, ecco uno stile che puoi usare su ItemsControl per virtualizzarlo:

   

Non mi piace il suggerimento di utilizzare un ListBox in quanto consentono la selezione di righe in cui non lo si desidera necessariamente.

È solo che il ItemsPanel predefinito non è un VirtualizingStackPanel . Devi cambiarlo: