Discussion:
Combo: DropDownList-Style, Richtiges Event
(zu alt für eine Antwort)
Thomas Schulz
2005-11-28 17:51:02 UTC
Permalink
Moin!

Wenn ich den Style 'DropDownList' für ein Windows.Forms.ComboBox-Control aktiviere,
feuert es bei jeder Tastatureingabe gleich 'SelectedIndexChanged'.
Ich wollte dieses Event eigentlich nutzen, um das ausgewählte Element auszuwerten,
das geht so aber nicht, wenn ich mehrere Items in der Box habe, die auf den gleichen
Buchstaben reagieren.
Ich möchte das Event auswerten, welches beim Bestätigen des richtigen Items durch Mausklick
oder Enter ausgelöst wird, stelle mich aber irgendwie an...
Unter VBA/ACCESS gibt es dieses 'AfterUpdate'-Event.
Sowas hätt ich gerne wieder.
Kennt jemand das Pendant in VB.Net?


Gruß,

Thomas Schulz
Peter Fleischer
2005-11-28 18:30:39 UTC
Permalink
Thomas Schulz wrote:
...
Post by Thomas Schulz
Wenn ich den Style 'DropDownList' für ein
Windows.Forms.ComboBox-Control aktiviere, feuert es bei jeder
Tastatureingabe gleich 'SelectedIndexChanged'. Ich wollte dieses
Event eigentlich nutzen, um das ausgewählte Element auszuwerten, das
geht so aber nicht, wenn ich mehrere Items in der Box habe, die auf
den gleichen Buchstaben reagieren. Ich möchte das Event auswerten,
welches beim Bestätigen des richtigen Items durch Mausklick
Thomas,
und wie wäre es mit dem Click-Ereignis?
Post by Thomas Schulz
oder
Enter ausgelöst wird,
Und hier KeyDown?
Post by Thomas Schulz
stelle mich aber irgendwie an... Unter
VBA/ACCESS gibt es dieses 'AfterUpdate'-Event. Sowas hätt ich gerne
wieder. Kennt jemand das Pendant in VB.Net?
Click und KeyDown? Oder, wenn das Control verlassen wird, Leave?

Peter
Thomas Schulz
2005-11-28 19:52:48 UTC
Permalink
Hallo Peter,
Post by Peter Fleischer
und wie wäre es mit dem Click-Ereignis?
Click ist suboptimal :-(
Feuert ja schon, bevor überhaupt was Sinnvolles selektiert ist.
Schon beim ersten 'Anfassen'.
Post by Peter Fleischer
Und hier KeyDown?
Grundsätzlich ja, hab ich jetzt mal so abgefangen:

Private Sub cmbFirmaName_KeyDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyEventArgs) _
Handles cmbFirmaName.KeyDown

If e.KeyCode = Keys.Enter Then
cmbFirmaName_AfterUpdate() 'mein (Hilfs)-Handler
End If

End Sub
Post by Peter Fleischer
Oder, wenn das Control verlassen wird, Leave?
Nö, soll vor dem Verlassen auslösen.
Simpler Hintergund: Ein Combo mit Kunden soll beim Auswählen eines Kunden
ein Stammdatenformular füllen.
Das Combo ist AutoComplete-aufgerüstet.

Ich hab auch schon versucht, das Klick-Event so abzufangen, dass erst bei selektiertem
Index ausgewertet wird.

If Me.cmbFirmaName.SelectedIndex > 0 Then
cmbFirmaName_AfterUpdate()
End If

ABER:
Problem 1:
Select wird erst nach Klick ausgelöst. Beim ersten Klick auf einen gewählten Item
geht der Schuß also ins Leere.
Problem 2:
Und beim zweiten Klick wählt er den (alten) ersten Item, da ich den selected Item auswerte.

Wird irgendwie nichts :-(

Noch 'ne Event-Idee?
Aber bitte nicht Doppelklick, das verwirrt den User bloß.

Thomas Schulz
Peter Fleischer
2005-11-29 04:06:32 UTC
Permalink
Thomas Schulz wrote:
...
Post by Thomas Schulz
Select wird erst nach Klick ausgelöst. Beim ersten Klick auf einen
gewählten Item geht der Schuß also ins Leere.
Thomas,
das kann man aber mit passendem Code realisieren.
Post by Thomas Schulz
Und beim zweiten Klick wählt er den (alten) ersten Item, da ich den
selected Item auswerte.
Wird irgendwie nichts :-(
Noch 'ne Event-Idee?
Aber bitte nicht Doppelklick, das verwirrt den User bloß.
Ich habe das mal ohne Code mit dem Designer im VS2005 gemacht und kann dir
nur empfehlen, dass auch mal auszuprobieren und den Code anzuschauen:

1. Northwind-Datenbank als Beispiel nutzen
2. New DataSource mit Customers und Orders
3. Customers als ComboBox einstellen
4. Orders als DataGridView einstellen
5. leere Form
6. SplitContainer platzieren
7. mit D&D Customers auf linkes Panel
8. mit D&D Orders auf rechtes Panel
9. DropDownList-Style einstellen

Mit jeder Auswahl in der ComboBox wird die Anzeige im Grid aktualisiert.

Peter
Thomas Schulz
2005-11-29 06:48:27 UTC
Permalink
Moin Peter,
Post by Peter Fleischer
Post by Thomas Schulz
Select wird erst nach Klick ausgelöst. Beim ersten Klick auf einen
gewählten Item geht der Schuß also ins Leere.
Thomas,
das kann man aber mit passendem Code realisieren.
gerade danach suche ich, werde aber irgendwie nicht fündig...
Muss ich möglicherweise die Mausposition auswerten, und den darunter liegenden Item finden?
Post by Peter Fleischer
Ich habe das mal ohne Code mit dem Designer im VS2005 gemacht und kann dir nur empfehlen, dass auch mal auszuprobieren und den
1. Northwind-Datenbank als Beispiel nutzen
2. New DataSource mit Customers und Orders
3. Customers als ComboBox einstellen
4. Orders als DataGridView einstellen
5. leere Form
6. SplitContainer platzieren
7. mit D&D Customers auf linkes Panel
8. mit D&D Orders auf rechtes Panel
9. DropDownList-Style einstellen
Mit jeder Auswahl in der ComboBox wird die Anzeige im Grid aktualisiert.
Ist das VS2005-spezifisch? Hab ich noch nicht.
Was bedeutet: 2. New DataSource mit Costumers und Orders?
Ich kann unter VS2003 mit dem Designer ein DataSet1 mit beiden Tabellen erstellen.
Meintest Du das?
Wie kann ich 3. vor 7. und 4. vor 8. einstellen?
Und wieso werden automatisch Aktualisierungs-Funktionen erstellt?
Muss wohl was Neues sein - hab ich nicht :-(

Könntest Du mir evtl. den entscheidenden Codeausschnitt (Ereignisbehandlung des Combo) posten?

Grüße

Thomas Schulz
Peter Fleischer
2005-11-29 08:03:09 UTC
Permalink
Thomas Schulz wrote:
...
Post by Thomas Schulz
Post by Peter Fleischer
das kann man aber mit passendem Code realisieren.
gerade danach suche ich, werde aber irgendwie nicht fündig...
Muss ich möglicherweise die Mausposition auswerten, und den darunter
liegenden Item finden?
Thomas,
so kompliziert ist das nicht. Erstellen ein DataSet mit 1 Tabelle für die
Stammdaten. An die ComboBox bindest du die Einträge für die Liste der
ComboBox. Im Stammdatenformular nutzt du für die Bindung den göeichen
BindingManager. Damit laufen die im Stammdatenformular gebundenen Felder
synchron zum ausgewählten Eintrag in der ComboBox. Eine Auswertung
irgendeines Ereignisses ist da überhaupt nicht nötig.

...
Post by Thomas Schulz
Ist das VS2005-spezifisch? Hab ich noch nicht.
Dann kannst du es natürlich so nicht machen:-(
Post by Thomas Schulz
Was bedeutet: 2. New DataSource mit Costumers und Orders?
VS2005-spezifische = neue Feature.
Post by Thomas Schulz
Ich kann unter VS2003 mit dem Designer ein DataSet1 mit beiden
Tabellen erstellen. Meintest Du das?
Praktsich ist das analog. Das DataSet im FW2.0 kann aber zusätzlich noch
einen TableAdapter (entspricht DataAdapter) verwalten.
Post by Thomas Schulz
Wie kann ich 3. vor 7. und 4. vor 8. einstellen?
Das musst du in VS2003 mit entsprechendem Binding per Code arbeiten.
Post by Thomas Schulz
Und wieso werden automatisch Aktualisierungs-Funktionen erstellt?
Muss wohl was Neues sein - hab ich nicht :-(
Könntest Du mir evtl. den entscheidenden Codeausschnitt
(Ereignisbehandlung des Combo) posten?
Warum brauchst du das, wenn es doch mit dem BindingManager automatisch
möglich ist?

Peter
Thomas Schulz
2005-11-29 08:22:46 UTC
Permalink
Hallo Peter,
so kompliziert ist das nicht. Erstellen ein DataSet mit 1 Tabelle für die Stammdaten. An die ComboBox bindest du die Einträge für
die Liste der ComboBox. Im Stammdatenformular nutzt du für die Bindung den göeichen BindingManager. Damit laufen die im
Stammdatenformular gebundenen Felder synchron zum ausgewählten Eintrag in der ComboBox. Eine Auswertung irgendeines Ereignisses
ist da überhaupt nicht nötig.
wir sind mal wieder beim 'gewählten Eintrag'!
*Was ist* der 'gewählte Eintrag' einer AutoCompleteComboBox?
Es ist ja nicht so, dass ich nicht die richtigen Daten nach der (endgültigen) Auswahl der ID
im Combo in meinem Stammdatenformular angezeigt bekomme.
Aber:
zwischendurch, bei jeder Änderung meines ComboBox-Index während der Eingabe,
eben auch!
Das will ich vermeiden, es fiel mir auch eher zufällig beim Debuggen auf.
Warum brauchst du das, wenn es doch mit dem BindingManager automatisch möglich ist?
Ich fülle meine Stammdaten in diesem Projekt per Code aus einem SQL-Datareader,
nicht per Databinding an einen Adapter.

Wenn es wirklich nur ein simples Event-Handling per Code ist, was o.g. Problem der
wiederholten Selektion eines AutoCompleteCombos vermeidet, würdest Du es mir bitte
trotzdem verraten?

Gruß,

Thomas Schulz
Peter Fleischer
2005-11-29 08:50:07 UTC
Permalink
Thomas Schulz wrote:
...
Post by Thomas Schulz
wir sind mal wieder beim 'gewählten Eintrag'!
*Was ist* der 'gewählte Eintrag' einer AutoCompleteComboBox?
Thomas,
bei DropDownList-Style gibt es nur gültige Einträge und der Datensatzzeiger
steht IMMER auf einem Eintrag. Damit wird immmer ein Datensatz im
Stammdatenformular angezeigt.
Post by Thomas Schulz
Es ist ja nicht so, dass ich nicht die richtigen Daten nach der
(endgültigen) Auswahl der ID im Combo in meinem Stammdatenformular
zwischendurch, bei jeder Änderung meines ComboBox-Index während der
Eingabe, eben auch!
Das will ich vermeiden, es fiel mir auch eher zufällig beim Debuggen auf.
Was willst du konkret vermeiden?
Post by Thomas Schulz
Post by Peter Fleischer
Warum brauchst du das, wenn es doch mit dem BindingManager
automatisch möglich ist?
Ich fülle meine Stammdaten in diesem Projekt per Code aus einem
SQL-Datareader, nicht per Databinding an einen Adapter.
Und warum so umständlich? Und was ist "Databinding an einen Adapter"?
Post by Thomas Schulz
Wenn es wirklich nur ein simples Event-Handling per Code ist, was
o.g. Problem der wiederholten Selektion eines AutoCompleteCombos
vermeidet, würdest Du es mir bitte trotzdem verraten?
Wenn du mir verrätst, wie der Bediner mitteilt, dass er mit der Eingabe
fertig ist, dann kann ich dir auch ein Ereignis nennen und einen passenden
Programmcode erstellen.

Peter
Thomas Schulz
2005-11-29 09:06:24 UTC
Permalink
Hallo Peter,
bei DropDownList-Style gibt es nur gültige Einträge und der Datensatzzeiger steht IMMER auf einem Eintrag. Damit wird immmer ein
Datensatz im Stammdatenformular angezeigt.
OK, nicht zu ändern. Also einen Ausweg über Abfangen des 'richtigen' Select-Ereignisses.
Was willst du konkret vermeiden?
Die zwischenzeitliche Anzeige von Datensätzen, die durch Selektion von ersten,
'passenden' Einträgen entsteht:
Wenn ich 'Müller' anzeigen will, soll 'Mann' noch nicht vorher angezeigt werden.
Und warum so umständlich? Und was ist "Databinding an einen Adapter"?
Umständlich deswegen, weil nur die wenigsten Daten der Abfrage wirklich 1:1 in die
Datenfelder übernommen werden. Es finden vorab einige Auswertungen, Umwandlungen
usw. statt. Ich möchte die Daten in diesem Falle gerne weiter per Datareader einlesen.

Mit 'Databinding an Adapter' meinte ich Datenbindung der Controls an ein Objekt, das
unter Zuhilfenahme eines DataAdapters mit Daten gefüllt wird.
Ich hoffe, diese Formulierung bietet keine weiteren Angriffsflächen ;-)
Wenn du mir verrätst, wie der Bediner mitteilt, dass er mit der Eingabe fertig ist, dann kann ich dir auch ein Ereignis nennen und
einen passenden Programmcode erstellen.
Wie weiter oben gepostet:
Die Eingabe in ein AutoCompleteCombo soll mit <Enter> oder Klick auf ein Item
abgeschlossen werden.
Das <Enter>-Ereignis habe ich bereits passend gehandelt.
Stehengeblieben und nicht mehr weitergekommen waren wir beim Klick-Event.

Gruß,

Thomas Schulz
Peter Fleischer
2005-11-29 10:20:04 UTC
Permalink
Thomas Schulz wrote:
...
Post by Thomas Schulz
Post by Peter Fleischer
Was willst du konkret vermeiden?
Die zwischenzeitliche Anzeige von Datensätzen, die durch Selektion
Wenn ich 'Müller' anzeigen will, soll 'Mann' noch nicht vorher angezeigt werden.
Thomas,
du willst also verhindern, dass der Anwender sofort den ausgewählten Eintrag
angezeigt bekommt. Er soll durch zusätzliche Aktivitäten die Auswahl
nochmals bestätigen. Wenn er beispielsweise "Mann" sucht und "M" eintippt,
dann darf der automatisch selektierte "Mann" nicht sofort angezeigt werden,
sondern erst, wenn der Anwender das nochmals bestätigt. Das finde ich
äußerst unproduktiv und würde solche Anwendung als unqualifiert ablehnen,
wenn es dafür nicht driftige Gründe gibt.
Post by Thomas Schulz
Post by Peter Fleischer
Und warum so umständlich? Und was ist "Databinding an einen Adapter"?
Umständlich deswegen, weil nur die wenigsten Daten der Abfrage
wirklich 1:1 in die Datenfelder übernommen werden. Es finden vorab
einige Auswertungen, Umwandlungen usw. statt. Ich möchte die Daten in
diesem Falle gerne weiter per Datareader einlesen.
Du nutzt als Datenpuffer lieber die Items-Auflistung in der ComboBox und
ergänzt zusätzlich Code für den Synchronisationsvorgang anstelle als Puffer
ein gebundenes Listenobjekt mit BindingManager für die Synchronisation zu
nutzen. Auch dafür sollte es driftige Gründe geben.
Post by Thomas Schulz
Mit 'Databinding an Adapter' meinte ich Datenbindung der Controls an
ein Objekt, das unter Zuhilfenahme eines DataAdapters mit Daten
gefüllt wird. Ich hoffe, diese Formulierung bietet keine weiteren
Angriffsflächen ;-)
Ein DataAdapter impliziert auch nur einen DataReader für das Füllen eines
DataTable-Objektes, welches als Listenobjekt fungiert.

...
Post by Thomas Schulz
Stehengeblieben und nicht mehr weitergekommen waren wir beim
Klick-Event.
Wenn ich es richtig verstanden habe, dann wäre SelectedIndexChanged das
passende Ereignis.

Peter
Thomas Schulz
2005-11-29 11:38:35 UTC
Permalink
Peter,
Post by Peter Fleischer
Thomas,
du willst also verhindern, dass der Anwender sofort den ausgewählten Eintrag angezeigt bekommt.
du hast doch selbst ein AutoCompleteCombo designt. Du weißt doch, weswegen.
Aufgabe eines solchen Controls ist es, dem Anwender eine sensitive Suche in umfangreichen
Datenbeständen zu ermöglichen.
In meinem Projekt geht es z.Bsp. um eine Auswahl aus zur Zeit mehr als 7.000 Kunden.
Das Ganze soll rasch vonstatten gehen, ohne große Suchdialoge.
Hier sind AutoCompleteCombos ganz hervorragend geeignet.
Es gibt zwar unter 7.000 Datensätzen über 100 'Müller', aber nur 3 'Müller, Gustav' und
nur noch einen in 'Musterstraße 12'.
Was bringt es dem Anwender, wenn er zwischendurch:
1. Maas, Heinrich (m)
2. Mühlbach, Claudia (ü)
3. Müller, Albert (l bis Leerzeichen)
4. Müller, Gernot (g)
5. Müller, Guntram (u)
sofort angezeigt bekommt?
Post by Peter Fleischer
Er soll durch zusätzliche Aktivitäten die Auswahl nochmals bestätigen. Wenn er beispielsweise "Mann" sucht und "M" eintippt, dann
darf der automatisch selektierte "Mann" nicht sofort angezeigt werden, sondern erst, wenn der Anwender das nochmals bestätigt.
Der automatisch selektierte 'Mann' wird ja angezeigt, aber in der DropDownList
des Combos, wo der Anwender sofort sieht, dass er einen weiteren Buchstaben
zur Qualifizierung der Suche eingeben muss.
Post by Peter Fleischer
Das finde ich äußerst unproduktiv und würde solche Anwendung als unqualifiert ablehnen, wenn es dafür nicht driftige Gründe gibt.
Die Vorgängeranwendung in ACCESS, die ich in diesem Projekt auf .NET portiere,
läuft seit Juli 2001 im täglichen Einsatz. Die AnwenderInnnen schwören genau auf diese
AutoCompleteFunktion! ;-)
Sie würden mir ein neues Projekt ohne dieses Feature nicht abnehmen.
Post by Peter Fleischer
Du nutzt als Datenpuffer lieber die Items-Auflistung in der ComboBox und ergänzt zusätzlich Code für den Synchronisationsvorgang
anstelle als Puffer ein gebundenes Listenobjekt mit BindingManager für die Synchronisation zu nutzen. Auch dafür sollte es
driftige Gründe geben.
Hatte ich versucht, darzustellen.
Richtig ist allerdings auch, dass ich auch nach einem Jahr .Net noch immer 'nasse Finger'
kriege, wenn ich mit gebundenen Controls arbeiten muss. Ist leider noch nicht meine
Abstraktionsebene :-(
Und sobald zusätzlich zur einfachen, editierbaren Datenanzeige weitere Vorgänge zu handeln
sind, ziehe ich mich noch auf meine erprobten 'alten' Methoden zurück, und codiere die
Inserts und Updates in die DB hart.
Post by Peter Fleischer
Ein DataAdapter impliziert auch nur einen DataReader für das Füllen eines DataTable-Objektes, welches als Listenobjekt fungiert.
Ich ahnte: da kommt noch was von Dir :-)
Post by Peter Fleischer
Wenn ich es richtig verstanden habe, dann wäre SelectedIndexChanged das passende Ereignis.
Wenn ich den Style 'DropDownList' für ein Windows.Forms.ComboBox-Control aktiviere,
feuert es bei jeder Tastatureingabe gleich 'SelectedIndexChanged'.
Ich wollte dieses Event eigentlich nutzen, um das ausgewählte Element auszuwerten,
das geht so aber nicht, wenn ich mehrere Items in der Box habe, die auf den gleichen
Buchstaben reagieren.
Ich möchte das Event auswerten, welches beim Bestätigen des richtigen Items durch Mausklick
oder Enter ausgelöst wird, stelle mich aber irgendwie an...
Unter VBA/ACCESS gibt es dieses 'AfterUpdate'-Event.
Sowas hätt ich gerne wieder.
Wie war das mit dem Topf und dem Loch ?
;-)

Ich kämpfe weiter.
Irgendwie krieg ich das schon hin, und wenn ich das Klick-Event überhaupt nicht mehr auswerte.
Peter Fleischer
2005-11-29 12:40:06 UTC
Permalink
Thomas Schulz wrote:
....
Post by Thomas Schulz
1. Maas, Heinrich (m)
2. Mühlbach, Claudia (ü)
3. Müller, Albert (l bis Leerzeichen)
4. Müller, Gernot (g)
5. Müller, Guntram (u)
sofort angezeigt bekommt?
Thomas,
was ist daran störend, dass während der Suche in der ComboBox die gebundenen
Controls der Navigation folgen? Wenn du das wirklich trennen willst, warum
nutzt du dann nicht einen separaten Button (was ich aber nicht machen
würde).
Post by Thomas Schulz
Post by Peter Fleischer
Er soll durch zusätzliche Aktivitäten die Auswahl nochmals
bestätigen. Wenn er beispielsweise "Mann" sucht und "M" eintippt,
dann darf der automatisch selektierte "Mann" nicht sofort angezeigt
werden, sondern erst, wenn der Anwender das nochmals bestätigt.
Der automatisch selektierte 'Mann' wird ja angezeigt, aber in der
DropDownList des Combos, wo der Anwender sofort sieht, dass er einen
weiteren Buchstaben zur Qualifizierung der Suche eingeben muss.
Ich meinte, dass nach Eingabe von ein paar Buchstaben bereits der gewünschte
Eintrag gefunden werden kann, der nach deiner Technologie nochmals zu
bestätigen ist. Das ist aus meiner Sicht unnötig.
Post by Thomas Schulz
Post by Peter Fleischer
Das finde ich äußerst unproduktiv und würde solche Anwendung als
unqualifiert ablehnen, wenn es dafür nicht driftige Gründe gibt.
Die Vorgängeranwendung in ACCESS, die ich in diesem Projekt auf .NET
portiere, läuft seit Juli 2001 im täglichen Einsatz. Die
AnwenderInnnen schwören genau auf diese AutoCompleteFunktion! ;-)
Niemand verlangt, dass die AutoComplete-Funktion nicht angeboten wird, im
Gegenteil, gerade damit kann die Bedienung effektiver sein.
Post by Thomas Schulz
Sie würden mir ein neues Projekt ohne dieses Feature nicht abnehmen.
Da stimme ich voll zu!
Post by Thomas Schulz
Post by Peter Fleischer
Du nutzt als Datenpuffer lieber die Items-Auflistung in der ComboBox
und ergänzt zusätzlich Code für den Synchronisationsvorgang anstelle
als Puffer ein gebundenes Listenobjekt mit BindingManager für die
Synchronisation zu nutzen. Auch dafür sollte es driftige Gründe
geben.
Hatte ich versucht, darzustellen.
Richtig ist allerdings auch, dass ich auch nach einem Jahr .Net noch
immer 'nasse Finger' kriege, wenn ich mit gebundenen Controls
arbeiten muss. Ist leider noch nicht meine Abstraktionsebene :-(
Gebundene Controls in VB.NET sind nicht mehr so schwer handelbar wie in VB6.
Es gibt aber trotzdem eine Reihe von Besonderheiten, die sich mit
ungebundenen Controls übersichtlicher und stabiler lösen lassen. Das
betrifft z.B. komplexere Prüfungen erfasster Daten. Das geht schon mit
Längenprüfungen los.
Post by Thomas Schulz
Und sobald zusätzlich zur einfachen, editierbaren Datenanzeige
weitere Vorgänge zu handeln sind, ziehe ich mich noch auf meine
erprobten 'alten' Methoden zurück, und codiere die Inserts und
Updates in die DB hart.
Gerade bei den Inserts und Updates hat AD.NET die Nase weit vorn. Dort
dürfte es die wenigsten Probleme geben, wenn es darum geht, DataAdapter,
DataTables usw. zu nutzen.

...
Post by Thomas Schulz
Post by Peter Fleischer
Wenn ich den Style 'DropDownList' für ein
Windows.Forms.ComboBox-Control aktiviere, feuert es bei jeder
Tastatureingabe gleich 'SelectedIndexChanged'.
Bei wird da snur gefeuert, wenn ich mit der Tastatur durch die Liste
navigiere. Beim Eintippen der Buchstaben wird nur der passende Teil der
Liste ohne Auslösen von 'SelectedIndexChanged' angezeigt.
Post by Thomas Schulz
Ich wollte dieses
Post by Peter Fleischer
Event eigentlich nutzen, um das ausgewählte Element auszuwerten, das
geht so aber nicht, wenn ich mehrere Items in der Box habe, die auf
den gleichen Buchstaben reagieren.
Dann beschreibe mal die Einstellungen deiner ComboBox.

Ich habe es gestestet mit AutoCompleteMode=Suggest.
Post by Thomas Schulz
Ich möchte das Event auswerten,
Post by Peter Fleischer
welches beim Bestätigen des richtigen Items durch Mausklick oder
Enter ausgelöst wird, stelle mich aber irgendwie an... Unter
VBA/ACCESS gibt es dieses 'AfterUpdate'-Event. Sowas hätt ich gerne
wieder.
Das klappt bei mir mit 'SelectedIndexChanged' genau wie mit 'AfterUpdate' in
Access.

Peter
Thomas Schulz
2005-11-29 14:12:12 UTC
Permalink
Hallo Peter,
Post by Peter Fleischer
Thomas,
was ist daran störend, dass während der Suche in der ComboBox die gebundenen Controls der Navigation folgen? Wenn du das wirklich
trennen willst, warum nutzt du dann nicht einen separaten Button (was ich aber nicht machen würde).
wie bereits erwähnt werden mit dem Selektieren eines Items nicht nur zusätzliche Daten
im Form angezeigt. Es werden in Abhängigkeit von diesen Daten weitere Funktionen ausgeführt,
darunter das Auswerten eines Textes, das Neuladen einer weiteren ComboBox, das Vergleichen
der ursprünglich im Form angezeigten Daten mit einem Merkstring zwecks Warnung vor Datenverlust
beim Neuladen ohne Rückspeichern, usw...
All dies ist nur wirklich nützlich für das 'richtige' Item, daher will ich unnötige Ausführungen unterbinden.
Post by Peter Fleischer
Ich meinte, dass nach Eingabe von ein paar Buchstaben bereits der gewünschte Eintrag gefunden werden kann, der nach deiner
Technologie nochmals zu bestätigen ist. Das ist aus meiner Sicht unnötig.
Der einzig passende Eintrag aus der DropDownList muss ohnehin irgendwie bestätigt werden.
Es ist ganz und gar üblich, dies per Enter oder Klick zu tun.
Wenn Du zu Start-> Alle Programme -> Microsoft SQL Server -> Enterprise Manager
gehst, dann gehst auch Du nicht davon aus, den Manager damit gestartet zu haben.
Post by Peter Fleischer
Gebundene Controls in VB.NET sind nicht mehr so schwer handelbar wie in VB6. Es gibt aber trotzdem eine Reihe von Besonderheiten,
die sich mit ungebundenen Controls übersichtlicher und stabiler lösen lassen. Das betrifft z.B. komplexere Prüfungen erfasster
Daten. Das geht schon mit Längenprüfungen los.
Bei mir kommt zusätzlich hinzu, dass ich zur Beschleunigung der Eingabe zulasse,
'gleichzeitig' einen neuen Master-Satz (Kunde) und einen ersten Child-Satz(Anzeige)
zu speichern. Das mache ich per Code, indem ich den erzeugten PK gleich zum FK
des Childs mache.
Post by Peter Fleischer
Gerade bei den Inserts und Updates hat AD.NET die Nase weit vorn. Dort dürfte es die wenigsten Probleme geben, wenn es darum geht,
DataAdapter, DataTables usw. zu nutzen.
Ich arbeite mich sachte ran, wenn nur nicht immer dieser Abgabe-Druck wäre :-(
Post by Peter Fleischer
Bei wird da snur gefeuert, wenn ich mit der Tastatur durch die Liste navigiere. Beim Eintippen der Buchstaben wird nur der
passende Teil der Liste ohne Auslösen von 'SelectedIndexChanged' angezeigt.
Das gelingt mir nicht nachzuvollziehen, weder mit der 'normalen' ComboBox',
noch mit Deiner AutoCompleteComboBox.
Post by Peter Fleischer
Das klappt bei mir mit 'SelectedIndexChanged' genau wie mit 'AfterUpdate' in Access.
Aber bei mir nicht.
Hier ein Testform, das AutoCompleteCombo ist das von deiner FAQ-Seite.

=====================
Public Class Form1
Inherits System.Windows.Forms.Form

#Region " Vom Windows Form Designer generierter Code "

Public Sub New()
MyBase.New()

' Dieser Aufruf ist für den Windows Form-Designer erforderlich.
InitializeComponent()

' Initialisierungen nach dem Aufruf InitializeComponent() hinzufügen

End Sub

' Die Form überschreibt den Löschvorgang der Basisklasse, um Komponenten zu bereinigen.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

' Für Windows Form-Designer erforderlich
Private components As System.ComponentModel.IContainer

'HINWEIS: Die folgende Prozedur ist für den Windows Form-Designer erforderlich
'Sie kann mit dem Windows Form-Designer modifiziert werden.
'Verwenden Sie nicht den Code-Editor zur Bearbeitung.
Friend WithEvents ComboBox1 As System.Windows.Forms.ComboBox
Friend WithEvents ComboBox2 As AutoCompleteComboBox
Friend WithEvents TextBox1 As System.Windows.Forms.TextBox

<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.ComboBox1 = New System.Windows.Forms.ComboBox
Me.ComboBox2 = New ComboTest.AutoCompleteComboBox
Me.TextBox1 = New System.Windows.Forms.TextBox
Me.SuspendLayout()
'
'ComboBox1
'
Me.ComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
Me.ComboBox1.Items.AddRange(New Object() {"AaaTest", "AabTest", "AbaTest", "AbbTest", "AbcTest", "BaaTest"})
Me.ComboBox1.Location = New System.Drawing.Point(40, 24)
Me.ComboBox1.Name = "ComboBox1"
Me.ComboBox1.Size = New System.Drawing.Size(121, 21)
Me.ComboBox1.TabIndex = 0
'
'ComboBox2
'
Me.ComboBox2.Items.AddRange(New Object() {"AaaTest", "AabTest", "AbaTest", "AbbTest", "AbcTest", "BaaTest"})
Me.ComboBox2.Location = New System.Drawing.Point(40, 72)
Me.ComboBox2.Name = "ComboBox2"
Me.ComboBox2.Size = New System.Drawing.Size(121, 21)
Me.ComboBox2.Sorted = True
Me.ComboBox2.TabIndex = 0
'
'TextBox1
'
Me.TextBox1.Location = New System.Drawing.Point(240, 48)
Me.TextBox1.Name = "TextBox1"
Me.TextBox1.TabIndex = 1
Me.TextBox1.Text = ""
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(400, 350)
Me.Controls.Add(Me.TextBox1)
Me.Controls.Add(Me.ComboBox1)
Me.Controls.Add(Me.ComboBox2)
Me.Name = "Form1"
Me.Text = "Form1"
Me.ResumeLayout(False)

End Sub

#End Region

Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
ComboBox1.SelectedIndexChanged
Me.TextBox1.Text = Me.ComboBox1.Items(Me.ComboBox1.SelectedIndex)
End Sub

Private Sub ComboBox2_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
ComboBox2.SelectedIndexChanged
Me.TextBox1.Text = Me.ComboBox2.Items(Me.ComboBox2.SelectedIndex)
End Sub
End Class

==============

Grüße, Thomas
Peter Fleischer
2005-11-30 06:50:56 UTC
Permalink
Thomas Schulz wrote:
...
Post by Thomas Schulz
wie bereits erwähnt werden mit dem Selektieren eines Items nicht nur
zusätzliche Daten im Form angezeigt. Es werden in Abhängigkeit von
diesen Daten weitere Funktionen ausgeführt, darunter das Auswerten
eines Textes, das Neuladen einer weiteren ComboBox, das Vergleichen
der ursprünglich im Form angezeigten Daten mit einem Merkstring
zwecks Warnung vor Datenverlust beim Neuladen ohne Rückspeichern,
usw... All dies ist nur wirklich nützlich für das 'richtige' Item,
daher will ich unnötige Ausführungen unterbinden.
Thomas,
lagere doch diese Aktivitäten in einen separaten thread aus. Der kann
arbeiten und bei jedem Neuanstoß wegen Navigation wird der noch nicht
fertige thread abgebrochen. Wenn er fertig ist bevor weiter navigiert wurde,
werden die Daten angezeigt. Was soll daran schlecht sein. Falls diese Last
zu groß ist, kann man den thread ein wenig warten lassen (z.B. 200 ms), so
dass erst bei "längerem" Warten die arbeit angestossen wird.

...
Post by Thomas Schulz
Der einzig passende Eintrag aus der DropDownList muss ohnehin
irgendwie bestätigt werden. Es ist ganz und gar üblich, dies per
Enter oder Klick zu tun. Wenn Du zu Start-> Alle Programme ->
Microsoft SQL Server -> Enterprise Manager gehst, dann gehst auch Du
nicht davon aus, den Manager damit gestartet zu haben.
Das ist ein schlechter Vergleich. Nimm mal den Datei-Explorer mit
Ordnerleiste links. Wenn man sich durch den Tree bewegt, wird rechts auch
der dazugehörige Ordnerinhalt asynchron geladen und dann angezeigt. Da ist
kein zusätzlicher Klick erforderlich.
Post by Thomas Schulz
Post by Peter Fleischer
Gebundene Controls in VB.NET sind nicht mehr so schwer handelbar wie
in VB6. Es gibt aber trotzdem eine Reihe von Besonderheiten, die
sich mit ungebundenen Controls übersichtlicher und stabiler lösen
lassen. Das betrifft z.B. komplexere Prüfungen erfasster Daten. Das
geht schon mit Längenprüfungen los.
Bei mir kommt zusätzlich hinzu, dass ich zur Beschleunigung der
Eingabe zulasse, 'gleichzeitig' einen neuen Master-Satz (Kunde) und
einen ersten Child-Satz(Anzeige) zu speichern. Das mache ich per
Code, indem ich den erzeugten PK gleich zum FK des Childs mache.
Das geht aber mit DataAdapter und ein wenig Code auch problemlos.

...
Post by Thomas Schulz
Post by Peter Fleischer
Bei wird da snur gefeuert, wenn ich mit der Tastatur durch die Liste
navigiere. Beim Eintippen der Buchstaben wird nur der passende Teil
der Liste ohne Auslösen von 'SelectedIndexChanged' angezeigt.
Das gelingt mir nicht nachzuvollziehen, weder mit der 'normalen'
ComboBox', noch mit Deiner AutoCompleteComboBox.
Ich war immer davon ausgegangen, dass du dmit FW 2.0 und der darin
enthaltenen ComboBox mit AutoComplete arbeitest. Mit der ComboBox von meiner
Seite geht das so nicht. Im FW 1.1 wäre eine Lösung mit separater TextBox
und ListBox sinnvoll. Da kannst du dann genau deinen Algorithmus
implementieren. Jede Eingabe in der TextBox positioniert die Anzeige in der
ListBox ohne Auswahl eines Elementes. Erst mit Enter oder Klick wird
ausgewählt. Die Implementation wäre analog dem Beipiel auf meienr Site für
eine AutoComplete-TextBox möglich. Alles in ein User Control gepackt würde
diese Lösung als eigenes Control ergeben.

Peter
Thomas Schulz
2005-11-30 09:57:38 UTC
Permalink
Hallo Peter,

vielen Dank für Deine bisherigen Hinweise in diesem Thread.
lagere doch diese Aktivitäten in einen separaten thread aus. Der kann arbeiten und bei jedem Neuanstoß wegen Navigation wird der
noch nicht fertige thread abgebrochen. Wenn er fertig ist bevor weiter navigiert wurde, werden die Daten angezeigt. Was soll daran
schlecht sein. Falls diese Last zu groß ist, kann man den thread ein wenig warten lassen (z.B. 200 ms), so dass erst bei
"längerem" Warten die arbeit angestossen wird.
Das versuche ich mal, wobei ich mir den Umgang mit Threads auch erst aneignen muss.
Ich bin, wie gesagt, erst seit einem knappen Jahr mit einer 'echten' Sprache dabei,
habe vorher hauptsächlich mit VBA und ein wenig VB6 gearbeitet.
Das ist ein schlechter Vergleich. Nimm mal den Datei-Explorer mit Ordnerleiste links. Wenn man sich durch den Tree bewegt, wird
rechts auch der dazugehörige Ordnerinhalt asynchron geladen und dann angezeigt. Da ist kein zusätzlicher Klick erforderlich.
Die Diskussion zur Usability möchte ich hier gerne abschließen.
Mein Pflichtenheft sieht die 1:1 Übernahme der Klick/Enter Funktionalität der
Vorgänger-Applikation vor und ist für mich - auch aus eigener Überzeugung -
daher bindend. Ich werde das auf jeden Fall so umsetzen, weil ich der Meinung bin,
dass dies der Usability in diesem Fall sehr zuträglich ist.
Post by Thomas Schulz
Bei mir kommt zusätzlich hinzu, dass ich zur Beschleunigung der
Eingabe zulasse, 'gleichzeitig' einen neuen Master-Satz (Kunde) und
einen ersten Child-Satz(Anzeige) zu speichern. Das mache ich per
Code, indem ich den erzeugten PK gleich zum FK des Childs mache.
Das geht aber mit DataAdapter und ein wenig Code auch problemlos.
Hier habe ich mich inzwischen ziemlich vorangearbeitet, und bin echt erstaunt,
welche Funktionalitäten sich doch in dem Binding-Objekt verbergen.
Ich werde die Datenanzeige und -speicherung in gebundener Form realisieren.
Daraus sich neu ergebende Fragen folgen hier in einem neuen Thread.
Post by Thomas Schulz
Das gelingt mir nicht nachzuvollziehen, weder mit der 'normalen'
ComboBox', noch mit Deiner AutoCompleteComboBox.
Ich war immer davon ausgegangen, dass du dmit FW 2.0 und der darin enthaltenen ComboBox mit AutoComplete arbeitest. Mit der
ComboBox von meiner Seite geht das so nicht.
Eben... ;-)
Wie schnell man sich an neue Features gewöhnt...
Im FW 1.1 wäre eine Lösung mit separater TextBox und ListBox sinnvoll. Da kannst du dann genau deinen Algorithmus implementieren.
Jede Eingabe in der TextBox positioniert die Anzeige in der ListBox ohne Auswahl eines Elementes. Erst mit Enter oder Klick wird
ausgewählt. Die Implementation wäre analog dem Beipiel auf meienr Site für eine AutoComplete-TextBox möglich. Alles in ein User
Control gepackt würde diese Lösung als eigenes Control ergeben.
Ich verwende das MTGCComboBox Control von Flumeri/Silvestro
http://www.codeproject.com/vb/net/MultiColumnFlatCombo.asp

Das hat MultiColumn-Fähigkeit und bildet die Funktionalität der ACCESS-ComboBox
ausreichend nach.

Das mit dem Klicken kriege ich schon noch hin, und wenn ich's dem Control beibiege ;-)

Grüße

Thomas Schulz
Thomas Schulz
2005-11-30 18:10:11 UTC
Permalink
Hallo Peter,
Post by Peter Fleischer
Thomas,
lagere doch diese Aktivitäten in einen separaten thread aus. Der kann arbeiten und bei jedem Neuanstoß wegen Navigation wird der
noch nicht fertige thread abgebrochen. Wenn er fertig ist bevor weiter navigiert wurde, werden die Daten angezeigt. Was soll daran
schlecht sein. Falls diese Last zu groß ist, kann man den thread ein wenig warten lassen (z.B. 200 ms), so dass erst bei
"längerem" Warten die arbeit angestossen wird.
Ich habe es ohne separaten Thread jetzt so - möglicherweise eleganter - gelöst:

Dim PressedKey As Keys = Keys.Enter 'merkt letzte ComboTaste


Private Sub cmbFirmaName_SelectedIndexChanged(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles cmbFirmaName.SelectedIndexChanged
If PressedKey = Keys.Enter Then
cmbFirmaName_AfterUpdate() 'nur Enter als Taste darf bestätigen
End If
PressedKey = Keys.Enter 'für das Mausereignis! Das darf immer!
End Sub

Private Sub cmbFirmaName_KeyDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyEventArgs) Handles cmbFirmaName.KeyDown
pressedkey = e.KeyCode 'merken zum Testen
If PressedKey = Keys.Enter Then
cmbFirmaName_AfterUpdate() 'Enter anstelle Mausklick
End If
End Sub

Schönen Abend, und bis bald

Thomas Schulz

Loading...