Dans WPF zone de liste avec plus de 1000 Images, le Zoom des Images est lent
J'ai rencontré un problème lors de deveoping une photo d'application de l'observateur.
J'ai utiliser la liste pour Afficher les Images, qui est contenue dans une ObservableCollection.
Je lier la zone de liste de ItemsSource de l'ObservableCollection.
<DataTemplate DataType="{x:Type modeldata:ImageInfo}">
<Image
Margin="6"
Source="{Binding Thumbnail}"
Width="{Binding ZoomBarWidth.Width, Source={StaticResource zoombarmanager}}"
Height="{Binding ZoomBarWidth.Width, Source={StaticResource zoombarmanager}}"/>
</DataTemplate>
<Grid DataContext="{StaticResource imageinfolder}">
<ScrollViewer
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled">
<ListBox Name="PhotosListBox"
IsSynchronizedWithCurrentItem="True"
Style="{StaticResource PhotoListBoxStyle}"
Margin="5"
SelectionMode="Extended"
ItemsSource="{Binding}"
/>
</ScrollViewer>
J'ai aussi lier l'Image'height dans ListBox avec un curseur.(la Valeur du curseur également se lier à zoombarmanager.ZoomBarWidth.La largeur).
Mais j'ai découvert que si la collecte deviennent plus grands, tels que: contient plus de 1000 images, Si j'utilise le curseur pour modifier la taille des iamges, il est devenu un peu lent.
Ma Question est la.
1. Pourquoi est-il devenu Lent? devenir il essaie de zoom de toutes les images,ou c'est juste parce que notify("Largeur") est invoquée plus de 1000 fois.
2. Existe t'il une méthode pour résoudre ce genre de problème et de le rendre plus rapide.
La PhotoListBoxStyle est comme ceci:
<Style~~ TargetType="{x:Type ListBox}" x:Key="PhotoListBoxStyle">
<Setter Property="Foreground" Value="White" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}" >
<WrapPanel
Margin="5"
IsItemsHost="True"
Orientation="Horizontal"
VerticalAlignment="Top"
HorizontalAlignment="Stretch" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style~~>
Mais Si j'utilise le Style ci-dessus, je dois utiliser ScrollViewer en dehors de zone de liste, sinon je n'ai aucune idée de comment faire pour obtenir une surface lisse de défilement scrollerbar et le wrappanel semble avoir aucun défaut scrollerbar. Aider quelqu'un? Il est dit listbox avec scrollviewer a de mauvaises performances.
- La liaison de chaque image en Hauteur et en Largeur, c'est horriblement inefficace, il suffit d'utiliser un LayoutTransform sur le ItemsPanel (ajouté en réponse à cette effet).
Vous devez vous connecter pour publier un commentaire.
Le problème, c'est que votre nouvelle Mise en page du Panneau est le WrapPanel et il ne supporte pas la Virtualisation! Il est possible de créer votre propre Virtualisé WrapPanel... Lire en plus ici
Également lire davantage sur d'autres questions comme la mise en œuvre IScrollInfo ici
Je recommande fortement que vous ne créez pas un nouveau modèle de contrôle juste de remplacer le panneau de disposition... Plutôt procédez de la manière suivante:
L'avantage de ce mode est que vous n'avez pas besoin d'envelopper votre liste dans un scrollviewer!
[Mise à JOUR] Également lire cette article de Josh Smith! Pour faire le WrapPanel wrap... vous avez aussi n'oubliez pas de désactiver le défilement horizontal...
Je ne suis pas familier avec ce composant, mais en général il va y avoir des limitations sur le nombre d'éléments d'une liste peut afficher à la fois.
Une méthode pour résoudre ce genre de problème est de garder le nombre d'images affichées dans le contrôle à l'intérieur du numéro de la commande peut afficher à des niveaux de performance acceptables. Deux techniques pour ce faire sont la pagination ou le chargement dynamique.
Dans la pagination, vous ajoutez des contrôles pour basculer entre les discret blocs d'images, par exemple, de 100 à un moment, avec l'avant et à l'arrière des flèches, similaire à la navigation dans la base de données.
Avec le chargement dynamique, vous mettez en œuvre la pagination de derrière les scènes dans une telle manière que lorsque l'utilisateur fait défiler à la fin, l'application se charge automatiquement dans le prochain lot de photos, et peut-être même supprime un lot de vieux pour garder de la réactivité raisonnable. Il peut y avoir une petite pause comme cela se produit et il peut y avoir de travail nécessaire afin de garder le contrôle à la bonne défilement point, mais cela peut être un compromis acceptable.
Je vous recommande de ne pas lier la Largeur/Hauteur de la propriété de chaque image individuelle, mais plutôt de vous lier à un LayoutTransform sur la liste du ItemsPanel. Quelque chose comme:
essayer de virtualiser votre stackpael avec le VirtualizingStackPanel.IsVirtualizing="True" attachés à la propriété. cela devrait augmenter les performances.
à l'aide d'une listbox avec de nombreux éléments dans un scrollviewer est un autre problème de performance au sein de wpf. si vous le pouvez, essayez de vous débarrasser de la scrollviewer.
si votre itemtemplates sont un peu complexe, vous devriez envisager d'utiliser le Recyclage VirtualizationMode. cela indique à votre zone de liste pour la réutilisation des objets existants et en crée pas de nouvelles tout le temps.
Une partie du problème est que c'est le chargement de l'image dans chaque. Vous devez utiliser un
IValueConverter
pour ouvrir chaque image dans une taille de vignette, en définissant leDecodePixelWidth
ouDecodePixelHeight
propriétés sur leBitmapImage
. Voici un exemple que j'utilise dans un de mes projets...Quel est votre PhotoListBoxStyle style ressemble? Si c'est la modification de la zone de liste de ItemsPanelTemplate puis il ya une bonne chance de votre zone de liste n'est pas à l'aide d'un VirtualizingStackPanel que son sous-jacent panneau de la liste. Non virtualisé zones de liste sont beaucoup plus lent avec de nombreux articles.