| 

.NET C# Java Javascript Exception

1
Hallo,
ich verwende eine ListView mit GridView. Die einzelnen GridViewColumn werden wie folgt aufgebaut:

<GridViewColumn Header="Name">
<GridViewColumn.CellTemplate>
<DataTemplate>
<local:BindableTextBlock>
<local:BindableTextBlock.InlineCollection>
<MultiBinding Converter="{StaticResource wholeWordKeywordconverter}">
<Binding Path="Name"/>
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}" Path="DataContext.Keyword"/>
</MultiBinding>
</local:BindableTextBlock.InlineCollection>
</local:BindableTextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>


BindableTextBlock ist ein eigenes Usercontrol, abegelietet von TextBlock welches mir ermöglich einen Teil des Inhaltes Fett darzustellen. (z.B. Vorname) Dies erfolgt durch den Converter "wholeKeywordConverter". Da der Converter jetzt beim laden der Daten jede einzelne Zelle durchlaufen muss dauert das Anzeigen der Daten extrem lange.

Jetzt hab ich mir überlegt, den "Highlighter" nur dan zu aktivieren, wenn ListViewItem.IsMouseOver = true. Wie kann man das realisieren, bzw. ist es möglich den GridViewRowPresenter so zu manipulieren, dass standardmäßig eine ganz normale GridViewColumn erzeugt wird und erst bei IsMouseOver das CellTemplate von oben erzeugt wird. (allerdings für das gesamte ListViewItem, das ja aus mehreren GridViewColumns besteht)

Hoffe ich hab mein Anliegen halbwegs verständlich erklärt.
lg
19.03.2013
mrmee 745 1 8
3 Antworten
1
Nochmal zum Thema Performance: Wie viele Datensätze möchtest du denn anzeigen?

Ich habe mal einen Test mit 100.000 Datensätzen gemacht. Ich brauche hier zum Erzeugen meines Items (mit new) und Einfügen in die ObservableCollection (Add) 2,5 Sekunden. Lasse ich das Einfügen weg, sind es noch ca. 1,2 Sekunden, d. h. ca. die Hälfte entfällt auf das Einfügen in die ObservableCollection.

Verlagere ich das Erzeugen der Objekte in eine Background-Task und ersetze den synchronen Aufruf von ObservableCollection.Add durch einen Invoke an den UI-Dispatcher, dann braucht der Background-Thread immer noch 2,0 Sekunden. Die gefühlte UI-Performance ist aber deutlich schlechter. Außerdme beschäftige ich damit 2 CPUs statt nur einer. Bringt also nichts.

Ich bin mir sicher, dass - wenn du immer noch ein Performance-Problem hast - deine ListBoxItems nicht virtualisiert sind.

Ansonsten ist die Lösung mit dem Converter und dem MultiBinding insbesondere mit RelativeSource=FindAncestor auf das MainWindow und anschließendem "drilldown" in den übergeordenete DataContext aus Performance-Sicht bedenklich. Ich habe es stattdessen so gelöst, dass ich den hervorzuhebenden Suchbegriff in meinem "MainViewModel" halte und eine Referenz auf das "MainViewModel" in jedes "ItemViewModel" hineinreiche. Ändert sich der Suchbegriff, lösche ich das Datenmodell mit den markierten Suchbegriffen in allen "ItemViewModel"s. Erst wenn das Datenfeld für die Anzeige angefragt wird (über DataBinding), baue ich es wieder auf (sozusagen "on demand" bzw. "lazy loading").
21.03.2013
candritzky 66 1
Ich verwende eine ListView mit einer GridView als ListView.View. Das ist soweit auch performant. Allerdings nur solange ich das Highlighting nicht aktiviert habe. (Hab ich mit einem Profiler gemessen) Also hab ich mir gedacht die Wörter nur dann zu Highlighten, wenn die Zeile IsMouseOver hat. Deinen Tip mit dem weiterreichen des Keyword in mein ItemViewModel werd ich noch versuchen. Vielleicht bringt mich das auch schon weiter. Danke.
mrmee 22.03.2013
Also nur zur Information. Ich hatte einen GroupStyle im XAML definiert. Dieser hat anscheinend das Virtualisieren meiner ListView ziemlich gestört. Wenn ich nur den Teil mit meinem GroupStyle auskommentieren, sind meine 1000 Treffer auch schnell geladen.
mrmee 26.03.2013
0
Hi,

wenn Du unterschiedliche Views für den IsMouseOver-Zustand haben möchtest, kannst du das über einen Style mit einem Trigger erreichen.

Zuvor würde ich aber klären, WARUM die Performance so schlecht ist. Bist Du denn sicher, dass die Virtualisierung der ListBoxItems funktioniert? Du kannst das z. B. mit dem Snoop-Utility überprüfen. Wenn die Virtualisierung funktioniert, solltest du nur so viele ListBoxItems als Children deiner ListBox haben, wie auf dem Bildschirm zu sehen sind. Wenn du aber ein ListBoxItem je Datensatz hast, dann wird nicht virtualisiert und dann ist auch klar, dass die Performance in den Keller geht.

Viel Erfolg,
Chris
21.03.2013
candritzky 66 1
0
Nochmal zum Thema Performance: Wie viele Datensätze möchtest du denn anzeigen?

Ich habe mal einen Test mit 100.000 Datensätzen gemacht. Ich brauche hier zum Erzeugen meines Items (mit new) und Einfügen in die ObservableCollection (Add) 2,5 Sekunden. Lasse ich das Einfügen weg, sind es noch ca. 1,2 Sekunden, d. h. ca. die Hälfte entfällt auf das Einfügen in die ObservableCollection.

Verlagere ich das Erzeugen der Objekte in eine Background-Task und ersetze den synchronen Aufruf von ObservableCollection.Add durch einen Invoke an den UI-Dispatcher, dann braucht der Background-Thread immer noch 2,0 Sekunden. Die gefühlte UI-Performance ist aber deutlich schlechter. Außerdme beschäftige ich damit 2 CPUs statt nur einer. Bringt also nichts.

Ich bin mir sicher, dass - wenn du immer noch ein Performance-Problem hast - deine ListBoxItems nicht virtualisiert sind.

Ansonsten ist die Lösung mit dem Converter und dem MultiBinding insbesondere mit RelativeSource=FindAncestor auf das MainWindow und anschließendem "drilldown" in den übergeordenete DataContext aus Performance-Sicht bedenklich. Ich habe es stattdessen so gelöst, dass ich den hervorzuhebenden Suchbegriff in meinem "MainViewModel" halte und eine Referenz auf das "MainViewModel" in jedes "ItemViewModel" hineinreiche. Ändert sich der Suchbegriff, lösche ich das Datenmodell mit den markierten Suchbegriffen in allen "ItemViewModel"s. Erst wenn das Datenfeld für die Anzeige angefragt wird (über DataBinding), baue ich es wieder auf (sozusagen "on demand" bzw. "lazy loading").
21.03.2013
candritzky 66 1

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH