2010-12-28 13 views
13

Sto cercando di capire questa funzione di virtualizzazione, non sono sicuro se sto capendo male o cosa sta succedendo, ma sto usando il profiler di memoria ANTS per controllare il numero di elementi in un TreeView virtualizzato, e continua ad aumentare. Ho un TreeView con 1,001 elementi (1 radice, 1000 voci secondarie) e ottengo sempre fino a 1,001 TreeViewItems, 1,001 ToggleButtons e 1,001 TextBlocks. La virtualizzazione non dovrebbe riutilizzare gli articoli? Se è così, perché dovrei avere 1,001 di ciascuno? Inoltre, CleanUpVirtualizedItem non si attiva mai.WPF TreeView Virtualization

Fammi sapere se sto capendo questo errore e se hai delle risorse su come usarlo. Ho cercato su internet ma non ho trovato nulla di utile.

EDIT:

Anche la memoria utilizzata dal albero cresce da aporx. 4mb a 12mb quando espongo e scorro tutti gli elementi.

Fammi sapere grazie.

Questo è il mio codice.

XAML:

<Window x:Class="RadTreeViewExpandedProblem.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <Grid> 
     <TreeView x:Name="treeView" 
        VirtualizingStackPanel.IsVirtualizing="True" 
        VirtualizingStackPanel.CleanUpVirtualizedItem="TreeView_CleanUpVirtualizedItem"> 
      <TreeView.ItemsPanel> 
       <ItemsPanelTemplate> 
        <VirtualizingStackPanel /> 
       </ItemsPanelTemplate> 
      </TreeView.ItemsPanel> 
     </TreeView> 
    </Grid> 
</Window> 

C#:

public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 

      TreeViewItem rootItem = new TreeViewItem() { Header = "Item Level 0" }; 

      for (int i = 0; i < 1000; i++) 
      { 
       TreeViewItem itemLevel1 = new TreeViewItem() { Header = "Item Level 1" }; 

       itemLevel1.Items.Add(new TreeViewItem()); 

       rootItem.Items.Add(itemLevel1); 
      } 

      treeView.Items.Add(rootItem); 
     } 

     private void TreeView_CleanUpVirtualizedItem(object sender, CleanUpVirtualizedItemEventArgs e) 
     { 

     } 
    } 

risposta

4

Ok, il problema è che la virtualizzazione funziona solo quando TreeView utilizza Binding e non quando i nodi vengono generati uno alla volta nel codice come nell'esempio. Che peccato.

+2

Questo non dovrebbe essere un ostacolo troppo grande, basta usare una ObservableCollection per associare la vista ad albero e aggiungere i tuoi elementi alla raccolta quando necessario - questo è il più idiomatico Modo WPF comunque, non si desidera aggiungere manualmente gli oggetti direttamente. – BrokenGlass

+0

Mi piace la tua idea. Il modo in cui saprò quando ho bisogno di più elementi è quando scorri verso l'alto o verso il basso sull'albero. Pensi che funzionerebbe con questo approccio? – Carlo

+0

@Calro: certo, dovrebbe funzionare – Liero

4

La differenza è la virtualizzazione UI (che WPF supporta fuori dalla scatola sui controlli diversi) rispetto virtualizzazione dei dati (che WPF non supporta fuori la scatola).

Si riduce alla virtualizzazione dell'interfaccia utente rendendo solo ciò che è necessario e in vista; mentre la virtulizzazione dei dati tiene solo ciò che può essere necessario in un dato momento in memoria.

Bea ha due fantastici messaggi su UI virtualization e data virtualization e analizza le differenze e spiega come risolvere il problema dell'assenza di supporto per la virtualizzazione dei dati che sembra essere ciò che si sta cercando.

EDIT:

A partire dal 3.5 SP1 supporto per la virtualizzazione è stata aggiunta alla TreeView. Forse rimuovere il tuo modello ItemsPanel e basta impostare le proprietà su TreeView dovrebbe essere sufficiente.

+0

Lo capisco. Nella mia domanda sto parlando di UI Virtualization, che non capisco perché crea un contenitore per ognuno degli articoli 10001, nonostante la virtalizzazione sia impostata su true. – Carlo

+0

@Carlos Aggiunta la nota sulla rimozione del modello ItemsPanel; poiché credo che il modello predefinito di 3.5 SP1 dovrebbe essere un VirtualizingStackPanel, quindi non dovrebbe esserci alcuna necessità di cambiare il modello, basta abilitare la proprietà come si è fatto tramite TreeView. –

+0

Provato quello che hai menzionato nella tua modifica. Non ha funzionato neanche. Ho ancora un migliaio di controllo. Questo è veramente strano E ancora l'evento CleanUpVirtualizedItem non viene licenziato, il che è un altro indizio del fatto che la virtualizzazione non funziona. – Carlo

2

Questo non è preciso. Vero che virtualuzation funziona solo con il binding, tuttavia, come ho osservato in alcune applicazioni di esempio, il riciclaggio degli elementi si verifica solo sugli elementi radice della struttura ad albero.

quindi se si dispone di un solo articolo radice con 1000 bambini, non si verificherà alcun riciclo perché è disponibile solo 1 contenitore per il riciclaggio.

se si dispone di 100 articoli radice e ognuno di essi ha 100 figli, si otterrà il riciclaggio parziale, poiché verranno riciclati solo gli articoli radice 100, ma altri 9900 elementi figlio verranno archiviati nella memoria.

ovviamente il problema peggiora solo se il livello di nidificazione dell'albero è maggiore di 2 o 3.

Non so se esiste una soluzione a questo problema.