Autor |
Beitrag |
lapadula
      
Beiträge: 180
Erhaltene Danke: 10
|
Verfasst: Mi 30.11.16 17:59
Hallo ich habe eine Frage zur ComboBox in c#.
Wenn ein Item in der ComboBox augewählt wurde, dann wird eine ListView entsprechend der Wahl gefüllt.
Wenn ich ein Item per Mausrad auswähle, dann gibt es eine große Verzögerung beim befüllen der ListView. Klicke ich das Item jedoch mit der Maus an, wird die ListView viel schneller gefüllt.
Warum ist das so?
Moderiert von Th69: Titel leicht geändert.Moderiert von Th69: Topic aus Basistechnologien verschoben am Mi 30.11.2016 um 18:27
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mi 30.11.16 19:25
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
lapadula 
      
Beiträge: 180
Erhaltene Danke: 10
|
Verfasst: Mi 30.11.16 20:26
Ich nutze das IndexChanged-Ereignis und dieses wird auch nur ein Mal gefeuert.
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mi 30.11.16 20:35
Sicher das der nur einmal feuert?
Wenn ich vom ersten zum letzten Element mit dem Scrollrad scrolle (in der TextBox der Combobox nicht dem ListBox teil) gehe ich davon aus das alle Elemente mal ausgewählt waren und für alle ein IndexChanged Event gefeuert wird.
|
|
lapadula 
      
Beiträge: 180
Erhaltene Danke: 10
|
Verfasst: Mi 30.11.16 21:46
Ich habe in dem Event eine Zählervariable eingebaut, wenn mich nicht alles täuscht hat das Event immer nur einmal gefeuert.
Was passiert denn im Hintergrund beim scrollen, wieso feuert er beim Mausrad zwei mal?
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mi 30.11.16 21:54
Zitat: | Was passiert denn im Hintergrund beim scrollen, wieso feuert er beim Mausrad zwei mal? |
Er feuert nicht zweimal
Wenn ich z.B. 10 Elemente in der Combobox habe und vom 1.ten zum letzten scrolle sind alle dazwischen auch mal markiert. Ich bekomme also für jeden Wechsel den Event 1 mal. Also in diesem Beispiel 9mal. Für jedes Element einen außer dem ersten.
|
|
lapadula 
      
Beiträge: 180
Erhaltene Danke: 10
|
Verfasst: Mi 30.11.16 22:20
Aber warum gibt es dann solche großen Unterschiede in der Performance? Was macht er beim scrollen anders als beim draufklicken, auf ein Item.
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mi 30.11.16 22:27
Du bist auf dem 1.ten Element und klickst auf das 10.te Element. -> Du bekommst den SelectedIndex Event 1mal für das 10.te Element.
Du bist auf dem 1.ten Element und scrollst zum 10.ten. -> Du bekommst den SelectedIndex Event 1 mal für das 2.te, 3.te, 4.te, 5.te, ..... 10.te Element.
Das was im Event passiert machst du also 9mal anstatt 1mal. Noch einfacher kann ich es glaube ich nicht erklären 
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mi 30.11.16 22:45
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Mi 30.11.16 23:00
Mach mal eine Datenbankabfrage in SelectedIndexChanged um abhängig von der aktuellen Auswahl Daten in die ListView zu packen. Das wird auffallen.
|
|
lapadula 
      
Beiträge: 180
Erhaltene Danke: 10
|
Verfasst: Do 01.12.16 19:18
@Ralf Jansen vielen Dank nun hab ich das auch kapiert
Und genau das passiert, es wird eine Datenbank abgefragt und der Inhalt wird in die ListView geschrieben.
Kann man das irgendwie so hinbiegen, dass der beim scrollen nicht alle vorherigen Items beachtet?
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Do 01.12.16 19:55
Standardverfahren wäre die Aktion im Event nicht sofort auszuführen sondern erst wenn der Event nicht kurze Zeit später schon wieder auftritt.
Das hilft dann beim scrollen oder auch wenn man mit den Up/down Keyboard tasten schnell durch die Liste navigiert.
Z.B. etwa so mit einem Timer
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| private System.Timers.Timer timer;
public MeinLieberFormConstruktor() { InitializeComponent();
timer = new System.Timers.Timer(200); timer.SynchronizingObject = this; timer.AutoReset = false; timer.Elapsed += Timer_Elapsed; }
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { }
private void meineLiebeComboBox_SelectedIndexChanged(object sender, EventArgs e) { timer.Stop(); timer.Start(); } |
|
|
lapadula 
      
Beiträge: 180
Erhaltene Danke: 10
|
Verfasst: Do 01.12.16 21:04
Super, danke. Wird morgen direkt ausprobiert
|
|
lapadula 
      
Beiträge: 180
Erhaltene Danke: 10
|
Verfasst: Fr 02.12.16 12:00
@Ralf Jansen
Es muss einen Unterschied zwischen Scrollen und draufklicken geben.
Ich scrolle nicht vom 1. zum 10 Element, sondern vom 9. zum 10.
Ich beschreibe das mal genauer:
Combobox1 ist gefüllt mit 1500 Items, ich öffne die ComboBox und wähle ein Item aus. Dabei braucht er 200ms um das SelectedIndexChange-Event abzuarbeiten.
Nun schwebt die Maus über der Combobox, die Combobox ist geschlossen. Ich scrolle auf genau das selbe Item und dabei braucht er 1000ms mehr, als wenn ich draufklicke.
Nochmal:
In der ComboBox befinden sich
Item A
Item B
Item C
Ich befinde mich im Item B und KLICKE auf Item A -> 200ms
Ich befinde mich in Item B und SCROLLE auf Item A -> 1200ms
Selbst wenn ich die Methode, die die ListView füllt auskommentiere, gibt es dennoch einen Unterschied zwischen draufklicken und scrollen
Ich habe noch 2 weitere Events, die der ComboBox zugerodnet sind, aber diese sollten das Verhalten nicht verursachen.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| private void OnComboBox_KeyPress(object sender, KeyPressEventArgs e) { if (sender is ComboBox) (sender as ComboBox).DroppedDown = false; } private void OnComboBox_DropDown(object sender, EventArgs e) { if (sender is ComboBox) (sender as ComboBox).DroppedDown = false; } |
Im Hintergrund muss also etwas passieren, nur was?
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Fr 02.12.16 16:09
Zitat: | Ich habe noch 2 weitere Events, die der ComboBox zugerodnet sind, aber diese sollten das Verhalten nicht verursachen. |
Das würde ich so nicht unterschreiben. Eine Combobox ohne Combobox ist schon merkwürdig. Denn DropDown Teil zu schließen wenn er geöffnet wird löst sicher trotzdem irgendwelches Kontrolinternes synchronisieren zwischen DropDown und TextBox der Combobox aus.
Letztlich solltest du das aber debuggen also überprüfen welche Events wann von deinem Control ausgelöst wird und daraus dann die passenden Schlüsse ziehen.
|
|
lapadula 
      
Beiträge: 180
Erhaltene Danke: 10
|
Verfasst: Fr 02.12.16 16:50
Gut habe die Codezeilen in den beiden EventHandlern auskommentiert, wie erwaretet keine Besserung.
Die ComboBox löst nur und ausschließlich das IndexChanged-Event aus, sonst nichts.
Kann es an c# 2005 liegen?
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Fr 02.12.16 16:57
Eher nicht. Die Winforms Controls haben sich seit Äonen nicht geändert. Es ist eher ein prinzipielles Verhalten des Controls unabhängig von der benutzen Frameworkversion, Sprache oder IDE.
Wenn du kurz erklärst was das soll (ComboBox ohne Dropdown) habe ich vielleicht eine Lösung die zumindest theoretisch problemlos sein sollte.
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Sa 03.12.16 02:56
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
lapadula 
      
Beiträge: 180
Erhaltene Danke: 10
|
Verfasst: Sa 03.12.16 21:52
Die beiden anderen Events stammen nicht von mir, da könnte ich Montag nachfragen, wofür die da sind.
Die Laufzeitmessung habe ich in meine IndexChanged-Event eingebaut.
Einmal die
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| Stopwatch watch = new Stopwatch();
watch.Start();
...
watch.Stop(); Console.WriteLine("Measured time: " + watch.Elapsed.TotalMilliseconds + " ms."); |
und die
C#-Quelltext 1: 2: 3: 4: 5: 6:
| TimeSpan begin = Process.GetCurrentProcess().TotalProcessorTime;
...
TimeSpan end = Process.GetCurrentProcess().TotalProcessorTime; Console.WriteLine("Measured time: " + (end - begin).TotalMilliseconds + " ms."); |
Bei beiden Methoden, kommen zwar unterschiedliche Zeitwerte raus aber den Unterschied zwischen Klicken und Scrollen gibt es dennoch.
|
|
lapadula 
      
Beiträge: 180
Erhaltene Danke: 10
|
Verfasst: Mo 05.12.16 10:03
Ich weiss nun mehr über die 2 anderen Events bescheid.
Die comboBox hat die Eigenschaften AutoCompleteMode auf Suggest und AutoCompleteSource auf ListItems.
Wenn man nun z. B "Ab" eingbit, dann hat er die normale DropDown-Liste + die Liste wo er was zu "Ab" gefunden hat, angezeigt.
Dazu verhielt sich die comboBox nicht wie gewünscht beim auswählen der Items.
Deshalb hat man die DroppedDown auf false gesetzt.
|
|