ComboBox Problem

  • VB.NET

Es gibt 27 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    ComboBox Problem

    Moin Community...

    langsam geht mir die Hitze auch auf den Kopf.
    Ich bekomm es gerade nicht lauffähig hin, eine ComboBox mit Daten zu füttern.

    Mein Ausgangscode aus einem damaligen Projekt von mir...

    VB.NET-Quellcode

    1. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2. Dim con As New MySqlConnection
    3. Dim constr As String = "server=servername;uid=user;pwd=passwort;database=datenbank;"
    4. Try
    5. con.ConnectionString = constr
    6. con.Open()
    7. Catch ex As MySqlException
    8. MsgBox(ex.Message)
    9. Application.Exit()
    10. End Try
    11. Dim sStmt As String = "SELECT * FROM kunden ORDER BY matchcode ASC"
    12. Dim cmd As New MySqlCommand(sStmt, con)
    13. Dim da As MySqlDataAdapter = New MySqlDataAdapter(cmd)
    14. Dim dt As New DataTable("kunden")
    15. da.Fill(dt)
    16. If dt.Rows.Count > 0 Then
    17. ComboBox1.DataSource = dt
    18. ComboBox1.DisplayMember = "matchcode" 'What is displayed
    19. ComboBox1.ValueMember = "id" 'The ID of the row
    20. End If
    21. End Sub


    versuche ich jetzt verbissen seit 2 Stunden umzubauen das ich hier die Verfügbaren Laufwerke HDDs des PCs mit freiem Festplattenspeicher angezeigt bekomme.
    Verwendet wird folgender Code:

    VB.NET-Quellcode

    1. Dim volname As String
    2. For Each drv As IO.DriveInfo In IO.DriveInfo.GetDrives
    3. With drv
    4. If .DriveType = IO.DriveType.Fixed Then ' nur Festplatte
    5. volname = .VolumeLabel
    6. If volname = "" Then
    7. volname = "Namenlos"
    8. Else
    9. volname = .VolumeLabel
    10. End If
    11. cb_target.Items.Add(.Name & " (" & volname & ") (" & Math.Round(.TotalSize / 1024 ^ 3) & " GB)")
    12. End If
    13. End With
    14. Next



    Mein Ziel ist es, in der ComboBox alle verfügbaren HDDs anzeigen zu lassen, beim auswählen jedoch eine ID bzw. den Laufwerksbuchstaben zu übermitteln
    Beispielsweise wird der Wert "Lokaler Datenträger 488GB" ausgewählt soll nur als Value C: übergeben werden.
    Mit der MySQL Abfrage oben geht es ja auch das ich einen "Matchcode" auswähle aber eine "id" übermittelt wird.

    Danke und Grüße Stefan
    Nein! Doch! OHH!
    Gib der ComboBox doch einfach das ganze DriveInfo Objekt und arbeite wie in deinem anderen Code mit Displa- und ValueMember
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Hab meinen Code nochmal überarbeitet. Schreibe alles in die DT jedoch bekomme ich in der CB nur angezeigt "System.Data.DataRowView"

    Hier nochmal der Code:

    VB.NET-Quellcode

    1. Private Sub volumes()
    2. Dim tb As New DataTable
    3. tb.Columns.Add("Text", GetType(String))
    4. tb.Columns.Add("Value", GetType(String))
    5. Dim volname As String
    6. For Each drv As IO.DriveInfo In IO.DriveInfo.GetDrives
    7. With drv
    8. If .DriveType = IO.DriveType.Fixed Then ' nur Festplatte
    9. volname = .VolumeLabel
    10. If volname = "" Then
    11. volname = "Namenlos"
    12. Else
    13. volname = .VolumeLabel
    14. End If
    15. tb.Rows.Add("(" & volname & ") (Frei: " & Math.Round(.AvailableFreeSpace / 1024 ^ 3) & " GB)", .Name)
    16. End If
    17. End With
    18. Next
    19. cb_target.DataSource = tb
    20. End Sub


    was mach ich falsch?


    Wenn ich es ohne DataTable direkt in die ComboBox schieß ( cb_volume.Items.Add("(" & volname & ") (Frei: " & Math.Round(.AvailableFreeSpace / 1024 ^ 3) & " GB)"))
    wird es korrekt dargestellt.
    Nein! Doch! OHH!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „samson“ ()

    Weil Du, wie mrMo bereits schrieb, noch für die ComboBox DisplayMember und ValueMember festlegen musst. Sonst weiß die ComboBox nicht, welchen Teil sie von der DataTable darstellen soll, also welche Spalten.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Vor das End Sub hinzufügen:

    VB.NET-Quellcode

    1. cb_target.DisplayMember = "Text"
    2. cb_target.ValueMember = "Value"
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed Danke!
    Genau so hab ichs gemacht :) Hab es in dem alten Projekt dann doch noch gefunden gehabt.

    Bei der Hitze sollte man staatlich das Programmieren verbieten ^^
    Vielen Vielen Dank für Eure Hilfe! @VaporiZed und @mrMo

    Ich mach mich dann mal auf die Suche nach der nächsten Funktion die ich brauch :)
    (Kopieren einer 200GB Datei mit Ladebalkenanzeige ggf. Endzeit und das Asynchron)

    Neues Problem:
    Ich bekomm beim Select nicht das ValueMember angezeigt sondern immer nur "Value"
    Ausgabe in einem Label kommt als Text "Value"

    Screenshot angefügt.


    Code:

    VB.NET-Quellcode

    1. Private Sub volumes()
    2. Dim tb As New DataTable
    3. tb.Columns.Add("Text", GetType(String))
    4. tb.Columns.Add("Value", GetType(String))
    5. Dim volname As String
    6. For Each drv As IO.DriveInfo In IO.DriveInfo.GetDrives
    7. With drv
    8. If .DriveType = IO.DriveType.Fixed Then
    9. volname = .VolumeLabel
    10. If volname = "" Then
    11. volname = "Namenlos"
    12. Else
    13. volname = .VolumeLabel
    14. End If
    15. tb.Rows.Add(.Name & "(" & volname & ") (Frei: " & Math.Round(.AvailableFreeSpace / 1024 ^ 3) & " GB)", "1")
    16. End If
    17. End With
    18. Next
    19. cb_target.DataSource = tb
    20. cb_target.DisplayMember = "Text"
    21. cb_target.ValueMember = "Value"
    22. End Sub


    VB.NET-Quellcode

    1. Private Sub cb_target_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cb_target.SelectedIndexChanged
    2. lbl_status.Text = cb_target.ValueMember
    3. End Sub

    Nein! Doch! OHH!

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „samson“ ()

    Du hast das ganze doch schon mal gemacht gehabt. Offenbar kopierst du nur Code zusammen ohne zu wissen was er macht...

    lbl_status.Text = cb_target.ValueMember ist ja auch falsch. cb_target.ValueMember gibt dir einfach nur den Namen der Spalte (in diesem Fall) welche du als ValueMember gesetzt hattest. Die Combobox hat noch andere Selected... Properties. Was da die Richtige ist, wirst du sicher selber rausfinden ...
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    @mrMo Ich verstehe den alten sowie den neuen Code, das ist nicht das Problem...
    Im alten Projekt funktioniert der Code auch genau so, wie er da steht... Daher verstehe ich nicht wo ich den Fehler im neuen Code gemacht habe.
    Übrigends... ist er nicht kopiert sondern von hand abgeschrieben... damit bleibt mehr im Kopf hängen :)
    Nein! Doch! OHH!

    samson schrieb:

    Daher verstehe ich nicht wo ich den Fehler im neuen Code gemacht habe.

    mrMo schrieb:

    lbl_status.Text = cb_target.ValueMember ist ja auch falsch
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    @mrMo
    hab meinen Fehler gefunden.
    lbl_status.Text = cb_target.SelectedValue.ToString
    das .ToString fehlte mir die ganze Zeit... Deswegen hat es eine Exception geworfen.
    Hab die Meldung die ganze Zeit falsch interpretiert. Soll vorkommen.

    in meinem "tool" sollen Windowsdienste gestoppt und gestartet werden bevor eine Datei umkopiert wird...
    Schau dir mal meine Lösung bitte an und sag mir, ob das so sinnig ist. Funktionieren tut es grundsätzlich schon...
    aber ob es "schön" ist, ist eine andere Frage.

    VB.NET-Quellcode

    1. Private Function stop_FBGMO()
    2. Dim check As Integer = 0
    3. Try
    4. Dim FBGMO As New ServiceController("FirebirdGuardianMEDICALOFFICE") 'FB Guardian
    5. FBGMO.Stop()
    6. System.Threading.Thread.Sleep(1500)
    7. If FBGMO.Status.Equals(ServiceControllerStatus.Stopped) Then
    8. pb_stopservices.Visible = True
    9. TextBox1.AppendText("stop_fbgmo_ok" & Environment.NewLine)
    10. Else
    11. MessageBox.Show("Konnte Dienst Firebird-Guardian nicht stoppen!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Stop)
    12. End If
    13. Catch ex As Exception
    14. MessageBox.Show("Konnte Dienst Firebird-Guardian nicht stoppen!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Stop)
    15. check = 0
    16. End Try
    17. End Function
    Nein! Doch! OHH!

    samson schrieb:


    Schau dir mal meine Lösung bitte an und sag mir, ob das so sinnig ist.
    Keine Ahnung ob das sinnig ist.
    1. Wozu der Try/Catch? Welche Fehler können denn da auftreten?
    2. Wozu das Sleep?
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    TryCatch wegen ggf. fehlenden Adminrechten. Damit würde es ein Fehler werfen.
    Ich frage im Form_Load nicht ab ob adminrechte da sind... muss ich noch ändern.
    Sleep, da die Dienste beim stoppen etwas brauchen,... und wenn ich den Status direkt danach abfrage, kommts zum Fehler.

    Ablauf was das Programm macht ist folgendes...

    Beim Klick auf den Sicherungsbutton werden 2 Dienste beendet, an diesen beiden "Guardian-Diensten" hängen jeweils noch dienste dran.
    Erst wenn alles beendet ist, soll die Datenbank umkopiert werden
    wenn die Datenbank kopiert ist, sollen die Dienste wieder gestartet werden, damit werden die anhängende Dienste ebenfalls gestartet.

    Nein! Doch! OHH!

    VB.NET-Quellcode

    1. Private Function stop_FBGMO()
    Die Function hat keinen Datentyp.
    Das bedeutet, du proggst Strict Off.
    Das bedeutet eine unbestimmbare Anzahl weiterer Schwachstellen / Fehler in deim Programm.
    Hier ist beschrieben, wie du ihnen auf die Schliche kommst:
    Visual Studio - Empfohlene Einstellungen
    Danke @ErfinderDesRades, hab ich umgestellt und "as Object" deklariert, war auch das einzigste.
    Ich habe aktuell noch das Problem das die Dienste teilweise sehr lange brauchen, bis diese gestoppt sind.
    Hat hier vielleicht jemand eine Idee, wie ich das am besten in einer Schleife prüfen kann und erst wenn alle beendet sind, der Nächste Schritt erfolgen soll?
    Sowas wie goto Anweisungen sollte man ja in der heutigen Programmierung nicht mehr nutzen.
    Nein! Doch! OHH!
    Da ich jetzt nicht Deinen dazu passenden Code hier finde:

    VB.NET-Quellcode

    1. Private Sub WaitForAllServiceStops()
    2. Do
    3. For Each Service In ServiceList
    4. If Not Service.HasStopped() Then Continue Do
    5. Next
    6. Exit Do
    7. Loop
    8. Exit Sub
    Wobei ServiceList und die .HasStopped-Methode natürlich Eigenimplementationen von Dir sein werden.
    Oder mit LINQ:

    VB.NET-Quellcode

    1. Private Sub WaitForAllServiceStops()
    2. Do
    3. If ServiceList.FirstOrDefault(Function(x) Not x.HasStopped) Is Nothing Then Exit Do
    4. Loop
    5. Exit Sub
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed Danke für deinen Code...
    Ich muss gestehen, ich verstehe ihn jedoch leider nicht.
    Aktuell Sieht es bei mir so aus...

    Ausgelöst über einen Button:

    VB.NET-Quellcode

    1. Private Async Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bt_dasi.Click
    2. TextBox1.AppendText("Sicherung gestartet" & Environment.NewLine)
    3. bt_dasi.Enabled = False
    4. stop_mo() 'Eine Datei zum stoppen einer Instanz von einem Programm
    5. stop_FBGMO() 'Dienst Nummer 1 stoppen
    6. stop_MOG() ''Dienst Nummer 2 stoppen
    7. Dim return_copy As String = Await Task.Run(Function() FileCopy(datapath + "\medoff.gdb", datapath + "\dasi_medoff.gdb")) 'Umkopieren der Datenbank
    8. TextBox1.AppendText(return_copy & Environment.NewLine) 'Debugzeile aktuell noch...
    9. pb_dasiready.Visible = True 'PictureBox anzeigen wenn Datensicherung erstellt ist
    10. start_mo() 'Sicherungsdatei (wie bei stop_mo() wieder entfernen
    11. start_FBGMO() 'Dienst 1 starten
    12. start_MOG() 'Dienst 2 starten
    13. Timer1.Enabled = True 'Timer um den Sicherungsbutton und den Status zurückzusetzen.
    14. End Sub


    eine der Subs:

    VB.NET-Quellcode

    1. Private Sub stop_FBGMO()
    2. Dim check As Integer = 0
    3. Try
    4. Dim FBGMO As New ServiceController("FirebirdGuardianMEDICALOFFICE") 'FB Guardian
    5. FBGMO.Stop()
    6. System.Threading.Thread.Sleep(1500)
    7. If FBGMO.Status.Equals(ServiceControllerStatus.Stopped) Then
    8. pb_stopservices.Visible = True
    9. TextBox1.AppendText("stop_fbgmo_ok" & Environment.NewLine)
    10. Else
    11. MessageBox.Show("Konnte Dienst Firebird-Guardian nicht stoppen!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Stop)
    12. End If
    13. Catch ex As Exception
    14. MessageBox.Show("Konnte Dienst Firebird-Guardian nicht stoppen!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Stop)
    15. check = 0
    16. End Try
    17. End Sub


    Ich habe immer wieder das Problem das die Dienste zu lange brauchen bis sie entweder gestoppt oder gestartet sind, damit kommt immer die Fehlermeldung mit "Konnte Dienst nicht stoppen".
    Der .Sleep(1500) reicht einfach nicht immer aus, da es von System zu System unterschiedlich lange dauert, möchte ich, das es "Just in Time" nach beenden des Dienstes weiter geht.
    Klar, ich könnte auch einfach den Sleep auf 3000 setzen, aber ob dies dann irgendwann reicht?! Bezweifel ich.
    Nein! Doch! OHH!
    Ok, dann nehme ich mal den 2. Codeblock her. Bau das in ne Schleife um. Und hau Try-Catch raus. Oder kommen da wirklich Exceptions? Wenn ja, von welchem Typ?

    VB.NET-Quellcode

    1. Private Sub Stop_FBGMO()
    2. Dim FBGMO As New ServiceController("FirebirdGuardianMEDICALOFFICE") 'FB Guardian
    3. FBGMO.Stop()
    4. For i = 1 To 10
    5. System.Threading.Thread.Sleep(150)
    6. If Not FBGMO.Status.Equals(ServiceControllerStatus.Stopped) Then Continue For
    7. pb_stopservices.Visible = True
    8. TextBox1.AppendText("stop_fbgmo_ok" & Environment.NewLine)
    9. Exit Sub
    10. Next
    11. MessageBox.Show("Konnte Dienst Firebird-Guardian nicht stoppen!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Stop)
    12. check = 0
    13. End Sub

    Ob Du jetzt 10x die Schleife durchgehst und jew. 150ms wartest, andere Werte nimmst oder gar jene Werte der Sub als Parameter übergibst, ist Dein Bier. Prost!
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.