Code für 2 modale Dialoge effektiver gestalten

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 3 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Code für 2 modale Dialoge effektiver gestalten

    Hallo,
    ich habe hier ein funktionierendes Programm, es sieht mir jedoch ein wenig unntötig kompliziert aus und ich würde mich freuen, wenn ihr mal drüberschaut.

    Zur Abfolge:


    Es gibt Globale Variablen:
    • Bildpfad als String-Array mit 12 Pfaden
    • Bildpfad2 als String-Array mit 12 Pfaden
    Form1, Sub Button_OK
    • Arrays leeren, falls vom vorigen Mal etwas drinsteht
    • Using: Form2 laden als modalen Dialog
    Form2, Sub auswählen
    • CommonOpenFileDialog mit Multiselect
    • Pfade werden auf Form1.Bildpfad gespeichert
    • Bilder werden in den Pictureboxen angezeigt
    • schließen
    Weiter mit Form1
    • Using: Form3 laden als modalen Dialog
    • in die Textboxen die Pfade schreiben
    • .Show
    Form3
    • Benutzer klickt auf die Checkboxen, deren Pfade er nicht haben will
    • schließen
    Weiter in Form1
    Es kann jetzt vorkommen, dass zum Beispiel Bildpfad[0] Nothing ist, Bildpfad[1] nicht, Bildpfad[2] wieder Nothing, usw. Daher werden alle Pfade, die nicht Nothing sind, ins Array Bildpfad2 kopiert. Dieses enthält demnach gegebenenfalls weniger Pfade. Form2 und 3 dienen zum Ausselektieren. Das ist das Ziel meines Codes. Noch eine Anmerkung: Der Benutzer kann bis zu 12 Bilder auswählen, muss er aber nicht. Aber weil meistens Bilder aussortiert werden müssen, gibt es vorsorglich 12 Pictureboxen
    letzten Endes bleiben 5 Pfade übrig. Oder 6. You get the idea.

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

    Form1.vb

    VB.NET-Quellcode

    1. Imports Microsoft.WindowsAPICodePack.Dialogs
    2. Public Class Form_main
    3. Public Bildpfad(11) As String
    4. Public Bildpfad2(11) As String
    5. Private Sub Button_Start_Click(sender As Object, e As EventArgs) Handles Button_Start.Click
    6. For i As Integer = 0 To Bildpfad2.Length - 1 Step 1
    7. Bildpfad(i) = ""
    8. Bildpfad2(i) = ""
    9. Next
    10. Using Form2 As New Form_Bilder_auswaehlen
    11. Dim DR As DialogResult = Form2.ShowDialog(Me)
    12. If DR <> DialogResult.OK Then 'Falls Form2 einfach wegge-x-t wurde, wird das hier abgefangen.
    13. Return
    14. End If
    15. End Using
    16. Using Form3 As New Form_entfernen
    17. Dim tb As TextBox() = {Form3.TextBox1, Form3.TextBox2, Form3.TextBox3, Form3.TextBox4, Form3.TextBox5, Form3.TextBox6, Form3.TextBox7, Form3.TextBox8, Form3.TextBox9, Form3.TextBox10, Form3.TextBox11, Form3.TextBox12}
    18. For i As Integer = 0 To Bildpfad.Count - 1 Step 1
    19. If Bildpfad(i) IsNot Nothing Then
    20. If String.IsNullOrEmpty(tb(i).Text) Then
    21. tb(i).Text = Bildpfad(i)
    22. End If
    23. End If
    24. Next
    25. Dim DR As DialogResult = Form3.ShowDialog(Me)
    26. If DR <> DialogResult.OK Then 'Falls Form3 einfach wegge-x-t wurde, wird das hier abgefangen.
    27. Return
    28. End If
    29. Dim cb As CheckBox() = {Form3.CheckBox1, Form3.CheckBox2, Form3.CheckBox3, Form3.CheckBox4, Form3.CheckBox5, Form3.CheckBox6, Form3.CheckBox7, Form3.CheckBox8, Form3.CheckBox9, Form3.CheckBox10, Form3.CheckBox11, Form3.CheckBox12}
    30. For i As Integer = 0 To 11 Step 1
    31. If Not cb(i).Checked Then
    32. Bildpfad2(i) = Bildpfad(i)
    33. End If
    34. Next
    35. End Using
    36. End Sub
    37. End Class


    Form2

    VB.NET-Quellcode

    1. Imports Microsoft.WindowsAPICodePack.Dialogs
    2. Public Class Form_Bilder_auswaehlen
    3. Private Sub Button_bestaetige_Click(sender As Object, e As EventArgs) Handles Button_bestaetige.Click
    4. If String.IsNullOrEmpty(TextBox13.Text) Then 'Testbox13 ist die erste, also oben links. Man soll nicht bestätigen können, wenn gar nichts vorhanden ist.
    5. Return
    6. End If
    7. schliessen()
    8. End Sub
    9. Private Sub schliessen()
    10. Me.Close()
    11. End Sub
    12. Private Sub Button_auswaehlen_Click(sender As Object, e As EventArgs) Handles Button_auswaehlen.Click
    13. Dim Zaehler As Integer = 0
    14. Dim Pfade() As String = {"", "", "", "", "", "", "", "", "", "", "", ""}
    15. Using OFD As New CommonOpenFileDialog
    16. OFD.Title = "Bilder zauswählen"
    17. OFD.Filters.Add(New CommonFileDialogFilter("JPEG", ".jpg"))
    18. OFD.Filters.Add(New CommonFileDialogFilter("Bitmap", ".bmp"))
    19. OFD.Filters.Add(New CommonFileDialogFilter("PNG", ".png"))
    20. OFD.Multiselect = True
    21. OFD.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
    22. OFD.IsFolderPicker = False
    23. OFD.RestoreDirectory = True
    24. If OFD.ShowDialog() = CommonFileDialogResult.Ok Then
    25. For i As Integer = 0 To OFD.FileNames.Count - 1 Step 1
    26. Form_main.Bildpfad(i) = OFD.FileNames(i)
    27. Pfade(i) = OFD.FileNames(i)
    28. Zaehler += 1
    29. Next
    30. Else
    31. Return
    32. End If
    33. End Using
    34. Dim pb As PictureBox() = {PictureBox1, PictureBox2, PictureBox3, PictureBox4, PictureBox5, PictureBox6, PictureBox7, PictureBox8, PictureBox9, PictureBox10, PictureBox11, PictureBox12}
    35. Dim tb As TextBox() = {TextBox13, TextBox14, TextBox15, TextBox16, TextBox17, TextBox18, TextBox19, TextBox20, TextBox21, TextBox22, TextBox23, TextBox24}
    36. For i As Integer = 0 To Zaehler - 1
    37. If Pfade(i) IsNot Nothing Then
    38. Using My_Bitmap As New Bitmap(Pfade(i))
    39. pb(i).Image = My_Bitmap
    40. tb(i).Text = Pfade(i)
    41. End Using
    42. End If
    43. Next
    44. End Sub
    45. Private Sub Form_Bilder_auswaehlen_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    46. If PictureBox1.Image IsNot Nothing Then
    47. PictureBox1.Image.Dispose()
    48. End If
    49. If PictureBox2.Image IsNot Nothing Then
    50. PictureBox2.Image.Dispose()
    51. End If
    52. If PictureBox3.Image IsNot Nothing Then
    53. PictureBox3.Image.Dispose()
    54. End If
    55. If PictureBox4.Image IsNot Nothing Then
    56. PictureBox4.Image.Dispose()
    57. End If
    58. If PictureBox5.Image IsNot Nothing Then
    59. PictureBox5.Image.Dispose()
    60. End If
    61. If PictureBox6.Image IsNot Nothing Then
    62. PictureBox6.Image.Dispose()
    63. End If
    64. If PictureBox7.Image IsNot Nothing Then
    65. PictureBox7.Image.Dispose()
    66. End If
    67. If PictureBox8.Image IsNot Nothing Then
    68. PictureBox8.Image.Dispose()
    69. End If
    70. If PictureBox9.Image IsNot Nothing Then
    71. PictureBox9.Image.Dispose()
    72. End If
    73. If PictureBox10.Image IsNot Nothing Then
    74. PictureBox10.Image.Dispose()
    75. End If
    76. If PictureBox11.Image IsNot Nothing Then
    77. PictureBox11.Image.Dispose()
    78. End If
    79. If PictureBox12.Image IsNot Nothing Then
    80. PictureBox12.Image.Dispose()
    81. End If
    82. End Sub
    83. End Class


    Form3

    VB.NET-Quellcode

    1. Public Class Form_entfernen
    2. Private Sub Button_OK_Click(sender As Object, e As EventArgs) Handles Button_OK.Click
    3. schliessen()
    4. End Sub
    5. Private Sub Form3_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
    6. If e.KeyCode = Keys.Enter Then
    7. schliessen()
    8. End If
    9. End Sub
    10. Private Sub schliessen()
    11. Me.Close()
    12. End Sub
    13. End Class
    Bilder
    • Form2.png

      18,49 kB, 1.368×749, 48 mal angesehen
    • Form3.png

      15,01 kB, 802×504, 50 mal angesehen
    Ist es zwingend notwendig, dass sich das ganze Geschehen auf 3 Forms abspielt? Wäre es auf einem Form z.B. mit einem TabControl, ließe sich das ein oder andere vereinfachen.
    Ein wenig kompakter für den Form2-Aufruf wäre - falls gewünscht:

    VB.NET-Quellcode

    1. Using Form2 As New Form_Bilder_auswaehlen
    2. If Form2.ShowDialog(Me) <> DialogResult.OK Then Return
    3. End Using

    In Form1: Wenn Du keine Arrays, sondern Listen verwendest, könntest Du das anfängliche Löschen etwas vereinfachen, da eine List(Of X) eine Clear-Methode hat.
    ab Zeile#21:

    VB.NET-Quellcode

    1. If Bildpfad(i) IsNot Nothing AndAlso String.IsNullOrEmpty(tb(i).Text) Then tb(i).Text = Bildpfad(i)

    In Form2: Wenn Du Zeile#38 klassenweit verfügbar machst, kannst Du den Code ab Z#53 mit einer For-Schleife stark eindampfen.
    U.a. bei Form3 bin ich etwas überrascht. Ich lager zwar auch viel aus. Aber welches Zweck erfüllt das Auslagern von Me.Close bei Dir?
    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.
    Aber welches Zweck erfüllt das Auslagern von Me.Close bei Dir?
    Ich weiß gar nicht mehr, warum das so war. Zum Glück ist das weg ^^

    VB.NET-Quellcode

    1. Public Class Form_entfernen
    2. Private Sub Button_OK_Click(sender As Object, e As EventArgs) Handles Button_OK.Click
    3. Me.Close()
    4. End Sub
    5. Private Sub Form3_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
    6. If e.KeyCode = Keys.Enter Then
    7. Me.Close()
    8. End If
    9. End Sub
    10. End Class


    Wenn Du Zeile#38 klassenweit verfügbar machst, kannst Du den Code ab Z#53 mit einer For-Schleife stark eindampfen.
    Erledigt

    VB.NET-Quellcode

    1. Private Sub Form_Bilder_auswaehlen_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    2. For i As Integer = 0 To pb.Length - 1 Step 1
    3. If pb(i).Image IsNot Nothing Then
    4. pb(i).Image.Dispose()
    5. End If
    6. Next
    7. End Sub


    Danke für den kompakteren Form2-Aufruf!!
    Das mit den Listen ist auch gut!

    Ist es zwingend notwendig, dass sich das ganze Geschehen auf 3 Forms abspielt? Wäre es auf einem Form z.B. mit einem TabControl, ließe sich das ein oder andere vereinfachen.
    Nun, ich hielt es zuerst für notwendig, weil aus Platzgründen. Gute Idee mit dem Tab-Control. Werde es morgen Nachmittag umsetzen.

    =====================
    Edit: Jetzt erinnere ich mich gerade, dass ich schon einmal List(of String) benutzen wollte, aber ich bekomme nicht die Collection der FileNames zugewiesen Erledigt

    Hier einmal der Vollständigkeit halber der neue Code

    Form1.VB

    VB.NET-Quellcode

    1. Imports Microsoft.WindowsAPICodePack.Dialogs
    2. Public Class Form_main
    3. Public Bildpfade1 As New List(Of String) From {"", "", "", "", "", "", "", "", "", "", "", ""}
    4. Public Bildpfade2 As New List(Of String)
    5. Private Sub Button_Start_Click(sender As Object, e As EventArgs) Handles Button_Start.Click
    6. Bildpfade1.Clear()
    7. Bildpfade2.Clear()
    8. Using Form2 As New Form_Bilder_auswaehlen
    9. If Form2.ShowDialog(Me) <> DialogResult.OK Then Return
    10. End Using
    11. Using Form3 As New Form_entfernen
    12. Dim tb As TextBox() = {Form3.TextBox1, Form3.TextBox2, Form3.TextBox3, Form3.TextBox4, Form3.TextBox5, Form3.TextBox6, Form3.TextBox7, Form3.TextBox8, Form3.TextBox9, Form3.TextBox10, Form3.TextBox11, Form3.TextBox12}
    13. For i As Integer = 0 To Bildpfade1.Count - 1 Step 1
    14. If Bildpfade1(i) IsNot Nothing AndAlso String.IsNullOrEmpty(tb(i).Text) Then
    15. tb(i).Text = Bildpfade1(i)
    16. End If
    17. Next
    18. Dim DR As DialogResult = Form3.ShowDialog(Me)
    19. If DR <> DialogResult.OK Then 'Falls Form3 einfach wegge-x-t wurde, wird das hier abgefangen.
    20. Return
    21. End If
    22. Dim cb As CheckBox() = {Form3.CheckBox1, Form3.CheckBox2, Form3.CheckBox3, Form3.CheckBox4, Form3.CheckBox5, Form3.CheckBox6, Form3.CheckBox7, Form3.CheckBox8, Form3.CheckBox9, Form3.CheckBox10, Form3.CheckBox11, Form3.CheckBox12}
    23. For i As Integer = 0 To Bildpfade1.Count - 1 Step 1
    24. If Not cb(i).Checked Then
    25. Bildpfade2.Add(Bildpfade1(i))
    26. End If
    27. Next
    28. End Using
    29. End Sub
    30. End Class


    Form2

    VB.NET-Quellcode

    1. Imports Microsoft.WindowsAPICodePack.Dialogs
    2. Public Class Form_Bilder_auswaehlen
    3. Private Sub Button_bestaetige_Click(sender As Object, e As EventArgs) Handles Button_bestaetige.Click
    4. If String.IsNullOrEmpty(TextBox13.Text) Then 'Testbox13 ist die erste, also oben links. Man soll nicht bestätigen können, wenn gar nichts vorhanden ist.
    5. Return
    6. End If
    7. Me.Close()
    8. End Sub
    9. Private Sub Button_auswaehlen_Click(sender As Object, e As EventArgs) Handles Button_auswaehlen.Click
    10. Using OFD As New CommonOpenFileDialog
    11. OFD.Title = "Bilder zauswählen"
    12. OFD.Filters.Add(New CommonFileDialogFilter("JPEG", ".jpg"))
    13. OFD.Filters.Add(New CommonFileDialogFilter("Bitmap", ".bmp"))
    14. OFD.Filters.Add(New CommonFileDialogFilter("PNG", ".png"))
    15. OFD.Multiselect = True
    16. OFD.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
    17. If OFD.ShowDialog() = CommonFileDialogResult.Ok Then
    18. For Each file As String In OFD.FileNames
    19. Form_main.Bildpfade1.Add(file)
    20. Next
    21. Else
    22. Return
    23. End If
    24. End Using
    25. Dim pb As PictureBox() = {PictureBox1, PictureBox2, PictureBox3, PictureBox4, PictureBox5, PictureBox6, PictureBox7, PictureBox8, PictureBox9, PictureBox10, PictureBox11, PictureBox12}
    26. Dim tb As TextBox() = {TextBox13, TextBox14, TextBox15, TextBox16, TextBox17, TextBox18, TextBox19, TextBox20, TextBox21, TextBox22, TextBox23, TextBox24}
    27. For i As Integer = 0 To Form_main.Bildpfade1.Count - 1 Step 1
    28. If Form_main.Bildpfade1(i) IsNot Nothing Then
    29. Using My_Bitmap As New Bitmap(Form_main.Bildpfade1(i))
    30. pb(i).Image = My_Bitmap
    31. tb(i).Text = Form_main.Bildpfade1(i)
    32. Application.DoEvents()
    33. End Using
    34. End If
    35. Next
    36. End Sub
    37. Private Sub Form_Bilder_auswaehlen_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
    38. Dim pb As PictureBox() = {PictureBox1, PictureBox2, PictureBox3, PictureBox4, PictureBox5, PictureBox6, PictureBox7, PictureBox8, PictureBox9, PictureBox10, PictureBox11, PictureBox12}
    39. Dim tb As TextBox() = {TextBox13, TextBox14, TextBox15, TextBox16, TextBox17, TextBox18, TextBox19, TextBox20, TextBox21, TextBox22, TextBox23, TextBox24}
    40. For i As Integer = 0 To pb.Length - 1 Step 1
    41. If pb(i) IsNot Nothing AndAlso pb(i).Image IsNot Nothing Then
    42. pb(i).Image.Dispose()
    43. End If
    44. Next
    45. End Sub
    46. End Class


    Die Arrays, die die Pictureboxen und Textboxen enthalten, konnte ich leider nicht global deklarieren. "pb() war nothing" war immer die Fehlermeldung.
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Bartosz“ ()

    Bartosz schrieb:

    VB.NET-Quellcode

    1. Dim tb As TextBox() = {Form3.TextBox1, Form3.TextBox2, Form3.TextBox3, Form3.TextBox4, Form3.TextBox5, Form3.TextBox6, Form3.TextBox7, Form3.TextBox8, Form3.TextBox9, Form3.TextBox10, Form3.TextBox11, Form3.TextBox12}
    2. ' ...
    Dieser Code gehört in die Form_entfernen, da machst Du einen Aufruf hin und organisierst das dort. Die TextBoxen sollten Private sein.
    Statt OFD.Filters.Add(...) machst Du OFD.Filter = "Images|*.jpg;*.bmp;*.png|Alle Dateien|*.*".
    Statt Application.DoEvents() machst Du ein .Update() auf die entsprechenden Controls.
    Das Disposen der Images sollte in der Prozedur Protected Overrides Sub Dispose(ByVal disposing As Boolean) erfolgen:

    VB.NET-Quellcode

    1. For Each pb In Me.Controls.OfType(Of PictureBox)()
    2. If pb(i).Image IsNot Nothing Then
    3. pb(i).Image.Dispose()
    4. End If
    5. Next
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!