2014-08-27 10 views
5

Ich verwende ein StackPanel, um mehrere Steuerelemente vertikal anzuordnen (z. B. Titel, Unterüberschriften, Listbox, Trennzeichen, Listbox usw.).Verbessern Sie die Leistung für große ListBox in StackPanel?

Das StackPanel ist ein Kind eines ScrollViewer, um sicherzustellen, dass sein Inhalt immer scrollbar ist.

Eines der Steuerelemente im StackPanel ist eine ListBox.

Ihre ItemsSource ist eine an eine riesige Sammlung gebundene Datenmenge, und für jedes Objekt wird ein komplexes DataTemplate verwendet.

Leider bekomme ich wirklich schlechte Leistung (hohe CPU/Speicher) damit.

Ich versuchte

  • die List-Box der Itemspanel auf einen VirtualizingStackPanel Einstellung und
  • zwingende seine Control nur einen Itemspresenter (die Scroll der List-Box entfernen).

Aber es gab keinen Unterschied in den Leistungen. Ich nehme an, das StackPanel gibt seinen internen Kindern während der Messung unendliche Höhe?

Wenn ich den ScrollViewer und das StackPanel durch andere Panels/Layouts (z. B. Grid, DockPanel) ersetzt habe und die Leistung deutlich verbessert wurde, liegt die Lösung in der Virtualisierung.

Gibt es eine Möglichkeit für mich, die CPU/Speicherleistung dieser Ansicht zu verbessern?

enter image description here

[Update 1]

Original-Beispielprojekt: http://s000.tinyupload.com/index.php?file_id=29810707815310047536

[Update 2]

I Restyling/Templating TreeView/TreeViewItems versucht, mit kommen das folgende Beispiel. Es dauert immer noch eine lange Zeit zu starten/selbe, hohe Speicherauslastung. Aber sobald es geladen ist, fühlt sich das Scrollen viel reaktionsfähiger als das Original-Sample an.

Frage mich, ob es noch eine andere Möglichkeit gibt, die Startzeit/Speicherauslastung weiter zu verbessern?

Restyled TreeView Projekt: http://s000.tinyupload.com/index.php?file_id=00117351345725628185

[Update 2]

pushpraj Lösung funktioniert wie ein Charme

  • Original:
    • Startup: 35s,
    • Speicher : 393 MB
    • Scrolling: Langsam
  • TreeView:
    • Startup: 18s,
    • Speicher 377MB,
    • Scrolling: Fast
  • pushpraj Lösung:
    • Startup : < 1s,
    • Speicher: 20MB,
    • Scrolling: Fast

Antwort

9

Sie vielleicht die maximale Größe der großen Listenfeld begrenzen und ermöglichen Virtualization

zB

<ListBox MaxHeight="500" 
     VirtualizingPanel.IsVirtualizing="true" 
     VirtualizingPanel.VirtualizationMode="Recycling" /> 

Dadurch aktiviert die ListBox nur ein paar Elemente und aktiviert einen scro llbar in der Listbox, um bei Bedarf zu den restlichen Elementen zu blättern.

zur gleichen Zeit Einstellung VirtualizationMode bis Recycling wird Ihnen helfen, die komplexen Datenvorlagen wieder zu verwenden, so dass die Notwendigkeit, sie für jedes Element erneut zu erstellen.


EDIT

hier eine Lösung auf Ihrer Probe basiert, habe ich CompositeCollection mit Virtualization verwendet das gewünschte zu erreichen.

XAML

<Grid xmlns:sys="clr-namespace:System;assembly=mscorlib" 
     xmlns:l="clr-namespace:PerfTest"> 
    <Grid.Resources> 
     <DataTemplate DataType="{x:Type l:Permission}"> 
      <StackPanel Orientation="Horizontal"> 
       <CheckBox /> 
       <TextBlock Text="{Binding Name}" /> 
       <Button Content="+" /> 
       <Button Content="-" /> 
       <Button Content="..." /> 
      </StackPanel> 
     </DataTemplate> 
     <CompositeCollection x:Key="data"> 
      <!-- Content 1 --> 
      <TextBlock Text="Title" 
         FontSize="24" 
         FontWeight="Thin" /> 
      <!-- Content 2 --> 
      <TextBlock Text="Subtitle" 
         FontSize="16" 
         FontWeight="Thin" /> 
      <!-- Content 3 --> 
      <CollectionContainer Collection="{Binding DataContext, Source={x:Reference listbox}}" /> 
      <!-- Content 4 --> 
      <TextBlock Text="User must scroll past the entire list box before seeing this" 
         FontSize="16" 
         FontWeight="Thin" 
         Padding="5" 
         TextWrapping="Wrap" 
         Background="#99000000" 
         Foreground="White" /> 
     </CompositeCollection> 
    </Grid.Resources> 
    <ListBox x:Name="listbox" 
      VirtualizingPanel.IsVirtualizing="True" 
      VirtualizingPanel.VirtualizationMode="Recycling" 
      ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
      ItemsSource="{StaticResource data}" /> 
</Grid> 

Code

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     var items = new ObservableCollection<Permission>(); 
     foreach (var i in Enumerable.Range(0, 10000).Select(i => new Permission() { Name = "Permission " + i })) 
     { items.Add(i); } 
     DataContext = items; 
    } 
} 

public class Permission 
{ 
    public string Name { get; set; } 
} 

da wir keine Datenvorlage für Zeichenfolge erstellen können, so änderte ich die Zeichenfolge Sammlung zu Permission Sammlung. Ich hoffe in deinem realen Projekt wäre es etwas Ähnliches.

geben Sie einen Versuch und sehen, ob dies nahe ist, was Sie brauchen.

Hinweis: Sie können bedenkenlos ignorieren, wenn es irgendeine Designer Warnung auf Collection="{Binding DataContext, Source={x:Reference listbox}}" ist

+0

die maximale Höhe des listbox Fixing würde 2 Scrollbalken erscheinen lassen (siehe http://i.imgur.com/s1MJ6BO.png?1) – jayars

+1

das ist wahr, aber zur gleichen Zeit kann Virtualisierung nur funktionieren, wenn die Höhe fest ist oder maximale Höhe definiert ist, kann es nicht für unbegrenzte Höhe arbeiten. Sie können vielleicht die kombinierte Sammlung verwenden, alle Elemente im Stackpanel kombinieren und alle in einer Listbox mit aktivierter Virtualisierung anzeigen. Wenn Sie den Code teilen, werde ich versuchen, Ihnen dabei zu helfen. – pushpraj

+0

Aktualisiert, um Beispielprojekt – jayars