ich arbeite gerade an einem Projekt und muss in WPF einen Listview
programmieren. Um mich in das Thema einzuarbeiten, habe ich versucht einen
Testaufbau einer Tabelle zu realisieren.
Die Darstellung meiner Testtabelle mit Dummydaten funktioniert so wie ich
mir das vorstelle sehr gut. Nur nach der Darstellung lässt die Performance
der Liste (150 Spalten und ab 1000 Zeilen müssen realisiert werden) sehr zu
wünschen übrig.
Die vertikale Scrollgeschwindigkeit sinkt bei dem oben genannten
Listenmodell ins bodenlose und die Prozessorauslastung steigt auf 100%. Wobei
die horizontale Scrollgeschwindigkeit akzeptabel bleibt.
Auch bei Änderungen an den Spaltenbreiten steigt die Auslastung auf 100% und
meine Form ist auf längere Zeit nicht mehr ansprechbar.
Nach längerer Suche im Internet zur Lösung meines Problems bin ich immer
wieder nur auf Einträge von Programmieren gestoßen, die das gleiche Problem
haben, aber es wurden keine Lösungsansätze genannt.
Ich bin mir fast sicher, das dieses Problem irgendetwas mit der Darstellung
und dem rendern der Grafiken zu tun hat. Doch meine Liste zwingt sogar einen
Rechner mit überdurchschnittlicher Leistung in die Knie.
Wer sich Codeauszüge näher betrachten möchte kann sich ja mal bei mir
melden. Ich kann dann das Projekt gerne einmal per Mail verschicken.
--> floria...@gmx.de
Ich hoffe, dass mir vielleicht hier jemand helfen kann. Danke
Florian
> Die Darstellung meiner Testtabelle mit Dummydaten funktioniert so wie ich
> mir das vorstelle sehr gut. Nur nach der Darstellung lässt die Performance
> der Liste (150 Spalten und ab 1000 Zeilen müssen realisiert werden) sehr
> zu
> wünschen übrig.
Ein control vom Drittanbieter wäre keine option?
http://www.infragistics.com/dotnet/netadvantage/wpf/xamdatagrid.aspx#Overview
scheint mir hier geeignet für dich.
Gruß
Michael
> Die Darstellung meiner Testtabelle mit Dummydaten funktioniert so wie ich
> mir das vorstelle sehr gut. Nur nach der Darstellung lässt die Performance
> der Liste (150 Spalten und ab 1000 Zeilen müssen realisiert werden) sehr zu
> wünschen übrig.
Letztlich müsstest Du etwas, was in Windows Forms
der VirtualMode ist, implemetieren. Das bedeutet,
nur bei Anforderung/Bedarf wird gezeichnet. Allerdings ist
das nicht standardmässig nativ in WPF so vorhanden:
[ListView Databinding virtualmode (WPF) : .NET Development : MSDN
Forums]
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/6d8e6f19-538a-4808-a5b0-4f6969041129/
[Nutzung grosser Datenmengen beim DataGridView]
http://dzaebel.net/DgvVirtual.htm
_____________________
Ggf. wäre natürlich auch über:
[WindowsFormsHost-Klasse (System.Windows.Forms.Integration)]
http://msdn.microsoft.com/de-de/library/system.windows.forms.integration.windowsformshost.aspx
wiederum das Winform-ListView einbindbar.
ciao Frank
--
Dipl.Inf. Frank Dzaebel [MCP/MVP C#]
http://Dzaebel.NET
Mache zwar selber (derzeit noch) nichts mit WPF, habe aber mal etwas
nachgeforscht und folgendes gefunden, was man NICHT tun sollte:
Embedding the ListView inside a StackPanel
Embedding the ListView inside a ScrollViewer
Not setting ScrollViewer.CanContentScroll to true
Having too many columns
Having UI Virtualization turned off (VirtualizingStackPanel.IsVirtualizing)
... und dann gibt es da noch jemanden, der angeblich selbst bei 1.000.000
Records noch "fantastische Geschwindigkeiten" schafft:
http://social.msdn.microsoft.com/forums/en-US/wpf/thread/3d7ec212-d0ba-42d5-89f2-187ea4b5c9db/
vielleicht hilft das etwas weiter :-)
bye,
Helmut
danke für eure rasche Hilfe. Ich möchte hier nur mal den Code posten um
verständlich zu machen was ich bis jetzt einsetze. Nur um zu vermeiden das
die Suche des Problems in die falsche Richtung läuft. :o)
---------- Window1.xaml
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"
Height="500"
Width="1000"
ResizeMode="CanResize"
Loaded="Window_Loaded">
<ListView Name="ListViewTest"
ItemsSource="{Binding}"
Margin="10,10,10,10">
</ListView>
</Window>
---------- Window1.xaml.cs
namespace WpfApplication1
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
watch.StartWatch();
ScrollViewer.SetIsDeferredScrollingEnabled(ListViewTest, false);
//ScrollViewer.SetIsDeferredScrollingEnabled(ListViewTest, true);
VirtualizingStackPanel.SetIsVirtualizing(ListViewTest, true);
VirtualizingStackPanel.SetVirtualizationMode(ListViewTest,
VirtualizationMode.Recycling);
//VirtualizingStackPanel.SetVirtualizationMode(ListViewTest,
VirtualizationMode.Standard);
string bind, header;
GridView GridViewTest = new GridView();
DataTable table = data.BuildDataTable();
watch.Start("Build Headers");
for (int i = 0; i < table.Columns.Count; i++)
{
GridViewColumn spalte = new GridViewColumn();
bind = table.Columns[i].ColumnName.ToString();
header = table.Columns[i].ColumnName.ToString();
spalte.DisplayMemberBinding = new Binding(bind); //{ Mode =
BindingMode.OneTime };
spalte.Header = header;
spalte.Width = 150;
GridViewTest.Columns.Add(spalte);
}
watch.Stop("Build Headers");
watch.Start("View Grid in Listview");
ListViewTest.View = GridViewTest;
watch.Stop("View Grid in Listview");
watch.Start("Bind Data Context to Listview");
this.ListViewTest.DataContext = table;
watch.Stop("Bind Data Context to Listview");
watch.StopWatch();
}
}
}
--> Die "Watch-Klasse" dient mir nur dazu, die Zeiten der einzelen Bereiche
zu messen. Hier liege ich überall im ms-Bereich. Außer halt beim erstellen
des datatable das um so länger dauert, je größer die table-anforderung ist ;o)
---------- data.cs
namespace WpfApplication1
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
static class data
{
static data()
{
}
static public DataTable BuildDataTable()
{
watch.Start("Build Table");
DataTable data_table = new DataTable("test_table");
int i1 = 1, i2 = 1;
int anz_spalten = 100;
int anz_zeilen = 1000;
data_table.Columns.Add("-");
while (i1 < anz_spalten)
{
data_table.Columns.Add("Spalte " + i1.ToString());
i1++;
}
i1 = 0;
while (i1 < anz_zeilen)
{
DataRow row = data_table.NewRow();
while (i2 < anz_spalten)
{
row[0] = "Zeile " + i1.ToString();
row[i2] = "Spalte " + i2 + " Wert " + i1;
i2++;
}
i2 = 1;
data_table.Rows.Add(row);
i1++;
}
watch.Stop("Build Table");
return data_table;
}
}
}
---------------------------------------------------------------------------
Erst einmal sorry für diesen Mega-Post, aber vielleicht hilfts ja. Und
vielen Dank für die schnellen Antworten und Hilfeversuche. Hoffentlich liegt
es nur an ner kleinen Einstellung. Kann ja nicht sein, dass so ein ListView
nicht hinzubekommen wäre.
ich mach momentan ein Beispiel für Paging mit Linq und dem Datagrid. gibt
dort nen kleines REAME, wo auch einige Infoquellen angegeben sind.
Hab mal eben, die aktuelle und lauffähige Beta in Netz gepackt, ist unter 1
MB gross: http://w2ww.de/downloads/exchangegui081017.zip .
WPF hat ja einigen Support für OnDemand loading, bei richtig grossen
Datenmengen, ziehe ich es aber vor selber nur die Daten zu laden, die ich
gerade brauche/anzeige.
Viele Grüße
Winfried Wille
hier auch eine recht gute generische
Implementation über virtuelle Listen:
[Ramon’s weblog » Blog Archive » Virtual collections (part 1)]
http://blog.ramondeklein.nl/?p=24
In einigen Fällen geht es auch
schon über:
[VirtualizingStackPanel-Klasse (System.Windows.Controls)]
http://msdn.microsoft.com/de-de/library/system.windows.controls.virtualizingstackpanel.aspx
aber hier ist die Referenz-Collection weiterhin sehr gross
und das Laden kann in einigen Fällen recht lange dauern.