2010-12-28 22 views
13

Estoy tratando de descubrir esta característica de virtualización, no estoy seguro si estoy entendiendo mal o qué está pasando, pero estoy usando el generador de perfiles de memoria ANTS para verificar el número de elementos en TreeView virtualizado, y sigue aumentando. Tengo un TreeView con 1,001 elementos (1 raíz, 1000 subpuntos), y siempre obtengo hasta 1,001 TreeViewItems, 1,001 ToggleButtons y 1,001 TextBlocks. ¿No se supone que la virtualización reutilice los artículos? Si es así, ¿por qué tendría 1,001 de cada uno? Además, CleanUpVirtualizedItem nunca se dispara.WPF TreeView Virtualization

Avísame si entiendo esto mal y si tienes recursos sobre cómo usarlo. He buscado en Internet pero no he encontrado nada útil.

EDIT:

Incluso la memoria utilizada por el árbol crece de aporx. 4mb a 12mb cuando me expando y me desplazo por todos los elementos.

Déjame saber gracias.

Este es mi código.

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) 
     { 

     } 
    } 

Respuesta

4

Bien, el problema es que la virtualización solo funciona cuando TreeView usa Binding, y no cuando los nodos se generan uno por uno en el código como en mi ejemplo. Qué fastidio.

+2

Eso no debería ser demasiado difícil, solo usa un ObservableCollection para unir la vista de árbol y agrega tus artículos a la colección cuando sea necesario - esta es la más idiomática De todos modos, WPF no quiere agregar elementos directamente. – BrokenGlass

+0

Me gusta tu idea. La forma en que sabré cuando necesito más elementos es cuando me desplazo hacia arriba o hacia abajo en el árbol. ¿Crees que eso funcionaría con este enfoque? – Carlo

+0

@Calro: seguro, debería funcionar – Liero

4

La diferencia es la interfaz de usuario de virtualización (que WPF apoya fuera de la caja en diferentes controles) frente a la virtualización de datos (que WPF no soporta de la caja).

Se reduce a la virtualización de UI, solo representa lo que se necesita y a la vista; mientras que la virtualización de datos solo contiene lo que puede ser necesario en un momento dado en la memoria.

Bea tiene dos grandes publicaciones acerca de UI virtualization y data virtualization y se adentra en las diferencias y cómo solucionar la limitación de que no hay soporte para la virtualización de datos que parece ser lo que está buscando.

EDIT:

Al se añadió 3,5 apoyo SP1 para la virtualización al TreeView. Tal vez sea suficiente eliminar la plantilla de ItemsPanel y simplemente establecer las propiedades en TreeView.

+0

Entiendo eso. En mi pregunta, me refiero a la virtualización de la interfaz de usuario, y por eso no entiendo por qué crea un contenedor para cada uno de los 10001 elementos, a pesar de que la virtualización se establece en verdadera. – Carlo

+0

@Carlos Se agregó una nota sobre la eliminación de su plantilla ItemsPanel; ya que creo que la plantilla predeterminada a partir de 3.5 SP1 debería ser VirtualizingStackPanel, por lo que no debería haber necesidad de cambiar la plantilla, solo habilite la propiedad como lo ha hecho a través de TreeView. –

+0

Probé lo que mencionaste en tu edición. Tampoco funcionó. Todavía estoy en mil con cada control. Esto es muy extraño. Y aún así, el evento CleanUpVirtualizedItem no se activa, que es otra pista de que la virtualización no funciona. – Carlo

2

Eso no es exacto. Es cierto que la virtualización solo funciona con el enlace, sin embargo, como observé en algunas aplicaciones de muestra, el reciclaje de elementos ocurre solo en los elementos raíz de la vista en árbol.

así que si solo tiene 1 elemento raíz con 1000 niños, no se reciclará porque solo hay 1 contenedor disponible para reciclar.

si tiene 100 elementos raíz y cada uno de ellos tiene 100 hijos, obtendrá un reciclaje parcial, ya que solo se reciclarán los 100 elementos raíz, pero se guardarán otros 9900 elementos secundarios en la memoria.

por supuesto, el problema empeora si el nivel de anidación de su árbol es mayor que 2 o 3.

No sé si hay una solución a este problema.