Benutzer mit den meisten Antworten
Combobox zeigt Inhalt doppelt an

Frage
-
Hallo Zusammen,
ich habe eine VB2008 Windowsanwendung, in der ich eine Combobox aus einer Abfrage auf eine Access 2010 Tabelle (A_Kategorie auf Tabelle Kategorie) anzeigen will.Nun zeigt mir diese Combobox jedesmal den gerade ausgewählten Text zweimal an. Dafür werden nicht alle Datensätze angezeigt. Das ist für den Anwender etwas verwirrend.
Die Combobox hat folgende Eigenschaften:
Text: A_KategorieBindingSource - Kategorie
DataSource: A_KategorieBindingSource
DisplayMember: Kategorie
ValueMember: KategorieIch möchte anschließend die Combobox als Auswahlmöglichkeit nutzen, um über ein Textfeld ein Feld einer anderen Tabelle zu ändern. Das klappt, nachdem gespeichert wurde.
SelectedValue: BuecherBindingSource - Kategorie
Anzeige in der Combobox:
Historisch
Unterhaltung
Historisch
Frauenroman
Sachbuch
Historisch
KrimiInhalt der Tabelle bzw. Abfrage:
Thriller
Krimi
Frauenroman
Sachbuch
Unterhaltung
HistorischIch komme nicht drauf, was ich falsch mache :-(
Wenn ihr vielleicht einen Tipp für mich habt?
Vielen Dank und schöne Grüße
Christina
Antworten
-
Hallo Michael,
dann hat man euch leider zu wenig und auch falsches beigebracht.
Insbesondere ist ein absolutes NO GO:
If reader.HasRows = False Then Exit Sub End If
Damit werden Reader und Connection nicht geschlossen, was auf Dauer Probleme nach sich ziehen kann. Eine überarbeitete Variante:
Private Sub DatenLesen() Const constr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\myFolder\myAccess2007file.accdb;Persist Security Info=False;" Const strsql As String = "SELECT Vorname, Nachname FROM Beispieltabelle WHERE ..." ' Leert die Combobox ComboBox1.Items.Clear() Using conn As New OleDbConnection(constr) conn.Open() Using cmd As New OleDbCommand(strsql, conn) Using reader = cmd.ExecuteReader() While reader.Read() ComboBox1.Items.Add(reader.GetString(0)) ComboBox1.Items.Add(reader.GetString(1)) End While End Using End Using End Using End Sub
die zudem kürzer - die Kommentare sind eh überflüssig bei solchem Trivial-Code
(ausgenommen ihr werdet dafür bezahlt ;-))Was hier fehlt: Datenzugriffscode sollte nicht direkt im Formularcode "versenkt" werden, denn langfristig führt das zu einem Wartungschaos:
Wo bitte greifen wir auf "Beispieltabelle" zu? (und alle fangen an zu suchen).Und letztendlich macht die BindingSource-Komponente keine "bösen" oder "unheimlichen" Dinge und man sollte sich damit vertraut machen.
Für den Fall, dass man Dir die using Anweisung nicht beigebracht hat, solltest Du Dich damit ebenso beschäftigen.
Und bitte nicht falsch verstehen: Diese Ratschläge sind gut gemeint - von einem Entwickler mit gut zwei Jahrzehnten auf dem Buckel.
Gruß Elmar
- Als Antwort vorgeschlagen Dennis Becker Dienstag, 18. September 2012 12:40
- Als Antwort markiert Robert BreitenhoferModerator Montag, 1. Oktober 2012 16:04
Alle Antworten
-
Hallo Christina,
Deine Kategorientabelle sollte besser einen Autowert als Primärschlüssel verwenden, -
z. B. als KategorieId, und diesen für den Verweis in Bücher verwenden -
ValueMember und SelectedValue wären dann eine KategorieID.Auch im DataSet solltest Du einen Fremdschlüssel mit Relation einrichten.
Willst Du nur mit Texten arbeiten, prüfe ob die Werte identisch sind. Auf der Datenbankseite müsste eine Beziehung mit Änderungsweitergabe existieren, damit Änderungen an der Bezeichnung an alle Bücher weitergegeben werden.
Gruß Elmar
-
Hallo Elmar,
ich habe in der Kategorie-Tabelle einen Autowert als Primärschlüssel. Ich wollte in der Tabelle Buecher den Text der Kategorie speichern. Die Beziehung muss ich einrichten, da hast du Recht.
Aber egal, was ich in dieser Combobox mache, es wird immer nach der ersten Auswahl falsch angezeigt. Ich nehme das SelectedValue heraus, ich ändere es auf die KategorieID, ich ändere das ValueMember, es funktioniert nicht. Die Tabelle hat aber die richtigen Daten, und beim Laden in die Combobox stimmt alles. Nur nach dem Auswählen eines Eintrags tritt der Fehler auf.- Bearbeitet sphinxx Montag, 27. August 2012 13:00
-
Hallo,
da kann ich mir direkt keinen Reim drauf machen.
Reine Vermutung: Irgendwo findet da im Code noch etwas statt.
Am besten entferne die ComboBox und BindingSource komplett,
kompiliere einmal und fange danach von vorne an.Speichern solltest Du besser nur die KategorieID.
Wenn Du den Text der Kategorie direkt sehen willst, füge sie als berechnetes Feld (über die Relation) ein. Ansonsten müsstest Du den Kategorietext eindeutig machen und für die Relation verwenden.Gruß Elmar
-
Um solchen Probleme zu umgehen fülle ich meine Comboboxen meistens manuell:
Public Sub DatenLesen() 'Leert die Combobox combobox1.items.clear() 'Variablen deklarieren Dim constr As String 'Beinhaltet den Connectionstring zur Datenbank Dim conn As OleDBConnection 'Ist die Datenleitung zur Datenbank Dim strsql As String 'Beinhaltet den Befehl an die Datenbank Dim reader As OleDBDataReader 'Ist das ReaderObjekt 'Verbindung zur Datenbank festlegen 'Variert leicht, je nachdem welcher Datenbanktyp 'Weitere Hilfe unter www.connectionstrings.com constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\myFolder\myAccess2007file.accdb;Persist Security Info=False;" 'Datenleitung wird definiert conn = New OleDBConnection(constr) 'Datenleitung wird geöffnet conn.Open() 'Datenbankbefehl wird definiert strsql = "SELECT Vorname, Nachname FROM Beispieltabelle WHERE ..." 'Befehlsobjekt wird vorbereitet Dim cmd As New OleDBCommand(strsql, conn) 'Befehlsobjekt wird ausgeführt und Ergebnis in das Readerobjekt zurückgegeben reader = cmd.ExecuteReader 'Prüfen, ob Datensätze gefunden wurden If reader.HasRows = False Then Exit Sub End If 'Readerobjekt durchlaufen und Daten ausgeben While reader.Read() combobox1.Items.Add(reader!Vorname) combobox1.Items.Add(reader!Nachname) End While 'Readerobjekt schliessen reader.Close() 'Verbindung zur Datenbank schliessen conn.Close() End Sub
Gruß Michael
- Bearbeitet mgross93 Mittwoch, 29. August 2012 13:24
-
Hallo Michael,
vielen Dank für deinen Tipp. Hattest du das gleiche Problem schon mal? Dann handelt es sich vielleicht um einen MS Bug?
Nunja... nicht direkt.
Habe es in der Ausbildung so beigebracht bekommen. Und da Abreiten wir eigentlich überhaupt nicht mit BindingSources. Wir ziehen uns die Datensätze direkt aus der DB oder dem gefülltem DataSet mit dem oben genanntem Code-Besipiel.
Gruß
-
Hallo Michael,
dann hat man euch leider zu wenig und auch falsches beigebracht.
Insbesondere ist ein absolutes NO GO:
If reader.HasRows = False Then Exit Sub End If
Damit werden Reader und Connection nicht geschlossen, was auf Dauer Probleme nach sich ziehen kann. Eine überarbeitete Variante:
Private Sub DatenLesen() Const constr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\myFolder\myAccess2007file.accdb;Persist Security Info=False;" Const strsql As String = "SELECT Vorname, Nachname FROM Beispieltabelle WHERE ..." ' Leert die Combobox ComboBox1.Items.Clear() Using conn As New OleDbConnection(constr) conn.Open() Using cmd As New OleDbCommand(strsql, conn) Using reader = cmd.ExecuteReader() While reader.Read() ComboBox1.Items.Add(reader.GetString(0)) ComboBox1.Items.Add(reader.GetString(1)) End While End Using End Using End Using End Sub
die zudem kürzer - die Kommentare sind eh überflüssig bei solchem Trivial-Code
(ausgenommen ihr werdet dafür bezahlt ;-))Was hier fehlt: Datenzugriffscode sollte nicht direkt im Formularcode "versenkt" werden, denn langfristig führt das zu einem Wartungschaos:
Wo bitte greifen wir auf "Beispieltabelle" zu? (und alle fangen an zu suchen).Und letztendlich macht die BindingSource-Komponente keine "bösen" oder "unheimlichen" Dinge und man sollte sich damit vertraut machen.
Für den Fall, dass man Dir die using Anweisung nicht beigebracht hat, solltest Du Dich damit ebenso beschäftigen.
Und bitte nicht falsch verstehen: Diese Ratschläge sind gut gemeint - von einem Entwickler mit gut zwei Jahrzehnten auf dem Buckel.
Gruß Elmar
- Als Antwort vorgeschlagen Dennis Becker Dienstag, 18. September 2012 12:40
- Als Antwort markiert Robert BreitenhoferModerator Montag, 1. Oktober 2012 16:04
-
-
Hi Elmar,
danke für die Korrektur meines Beispielcodes :) .
If reader.HasRows = False Then
Exit Sub
End IfDas schließen des Readers und der Connection hab ich aus zeitlichen Gründen vergessen zu erwähnen aber das mit den Using-Blocks ist eine Super Idee um den Code übersichtlicher und kleiner zu halten Vielen Dank :)
-
Ich kann da Elmar nur bestätigen. Beim Einsatz der ComboBox pur oder gekapselt, z.B. in einer Gridspalte, hatte ich noch nie Probleme, außer bei eigenen Fehlern, z.B. beim Laden per Code (ungebunden) im falschen Ereignis (z.B. Activate). Durch den mehrmaligen Aufruf kann zum mehrmaligen Laden gleicher Daten kommen. Das ist aber ein Problem nicht im Computer, sondern vor dem Computer.--
Viele Gruesse
Peter -
Hallo Elmar, hallo Michael, hallo Peter,
ich habe jetzt mal beide Versionen getestet, und da tritt mein Fehler nicht mehr auf. Da Elmar's Version kürzer ist, werde ich wohl mit dieser arbeiten.
Trotz Allem will ich auch nochmal das Binden an die Combobox im Formulardesigner versuchen.
Vielen Dank nochmals an Euch Alle.
Viele Grüsse
Christina -
Hallo sphinxx,
Ich gehe davon aus, dass die Antworten Dir weitergeholfen haben.
Solltest Du noch "Rückfragen" dazu haben, so gib uns bitte Bescheid.Grüße,
RobertRobert Breitenhofer, MICROSOFT
Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.