Visual Basic - Varaiblen Namen für ein Element?

... komplette Frage anzeigen

3 Antworten

Schau Dir mal meinen Vorschlag an.

Ich habe ein kleines Programm geschrieben, mit dem Du Deine Probleme sicher lösen kannst.

  Const ZeilenMax As Short = 7
Const Spaltenmax As Short = 7
Private PB(ZeilenMax, Spaltenmax) As PictureBox

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Zuordnen()
NUD1.Maximum = ZeilenMax
NUD2.Maximum = Spaltenmax
End Sub
' ------------------------------
Sub Zuordnen()
PB(0, 0) = PictureBox1
' usw .......... bis
PB(7, 7) = PictureBox64
End Sub

' ------------------------------
Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
setFocus(sender)
End Sub
' usw .......... bis
Private Sub PictureBox64_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox64.MouseDown
setFocus(sender)
End Sub

' -----------------------------

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
SetBColor(NUD1.Value, NUD2.Value)
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
PB_Clear()
End Sub

' -----------------------------

Sub SetBColor(ByVal Z As Short, ByVal S As Short)
If PB(Z, S).BackColor = Color.Blue Then
PB(Z, S).BackColor = Color.White
Else
PB(Z, S).BackColor = Color.Blue
End If
End Sub

Sub PB_Clear()
For Z As Short = 0 To ZeilenMax
For S As Short = 0 To Spaltenmax
PB(Z, S).BackColor = Color.White
Next
Next
End Sub

Sub GetCoord(ByVal PBx As PictureBox, ByRef Zeile As Short, ByRef Spalte As Short)
For S As Short = 0 To Spaltenmax
For Z As Short = 0 To ZeilenMax
If PB(Z, S) Is PBx Then
Zeile = Z
Spalte = S
Exit Sub
End If
Next
Next
End Sub

Sub setFocus(ByVal sender As PictureBox)
Dim Zeile, Spalte As Short
GetCoord(sender, Zeile, Spalte)
PB(Zeile, Spalte).Focus()
SetBColor(Zeile, Spalte)
End Sub


Ein bisschen Aufwand (64 mal jeweils) liegen in dem Anordnen der PictureBoxen, in Zuordnen und den PictureBox~_MouseDown 

Gruß Horst

Kommentar von Zetesafe
28.02.2016, 15:47

Ach du meine Güte. Da hast du dir ja richtig Arbeit gemacht um mir zu helfen. Vielen vielen Dank. Ich schaue gleich mal dass ich das eingebaut kriege.

1

Ich würde die Steuerelemente (Pictureboxen) zur Laufzeit per Code erzeugen (also "new System.Windows.Forms.PictureBox()", und dann Eigenschaften setzen), anstatt mit dem Designer.

Dann kannst Du die einzelnen Elemente (z. B. mittels zwei geschachtelter For-Schleifen, die jeweils von 0 bis 7 (für 8 Durchläufe) laufen), in ein (zweidimensionales) Array packen und über die Array-Indizes (0 ... 7, 0 ... 7) ansprechen.

Wenn Du nicht zwei numerische Indizes, sondern einen Buchstaben und eine Ziffer haben möchtest, dann musst Du den Buchstaben eben entsprechend "parsen". Das würde ich wie folgt umsetzen.

  1. Prüfen, ob der String überhaupt zwei Zeichen lang ist. Wenn nicht, irgendwie geeignet abbrechen (z. B. None zurückgeben). Wenn ja, fortfahren.
  2. Erstes Zeichen aus dem String extrahieren.
  3. In Lowercase umwandeln (damit es egal ist, ob man 'a' oder 'A' angibt).
  4. ASCII-Wert des Zeichens herausfinden und überprüfen, ob er zwischen 'a' und 'h' (jeweils einschließlich, also ">=" und "<=" als Vergleichsoperatoren) liegt. Wenn nicht, abbrechen wie oben, sonst fortfahren.
  5. Den Character 'a' abziehen (damit 'a' = 0, 'b' = 1, ...).
  6. Das Ergebnis dieses Vorgangs in einer Variable "idx_first" vom Typ Integer speichern.
  7. Zweites Zeichen aus dem String extrahieren.
  8. ASCII-Wert des Zeichens herausfinden und überprüfen, ob er zwischen '0' und '9' (jeweils einschließlich, also ">=" und "<=" als Vergleichsoperatoren) liegt. Wenn nicht, abbrechen wie oben, sonst fortfahren.
  9. Den Character '0' abziehen (damit '0' = 0, '1' = 1, ...).
  10. Das Ergebnis dieses Vorgangs in einer Variable "idx_second" vom Typ Integer speichern.
  11. Das Array, das Deine Steuerelemente enthält, an der Stelle (idx_first, idx_second) indizieren. Damit erhältst Du Zugriff auf das entsprechende einzelne Steuerelement. Dann eine Methode aufrufen oder eine Eigenschaft ändern.

Kommentar von Zetesafe
28.02.2016, 16:07

Vielen Dank für die Antwort.

1

Beispiel: frmInput.Controls("txtInput" & i) = i

Bei dir könnte es dann so aussehen
UserForm1.Controls("A" & i).BackColor = Color.Blue

Kommentar von NoHumanBeing
20.02.2016, 20:28

Ja, das sollte auch funktionieren.

Allerdings würde ich Elemente nicht wirklich über einen Namen ansprechen wollen. Der Name eines Controls sollte eigentlich mehr oder weniger belanglos sein und könnte durchaus auch "pictureBox1", "pictureBox2", ... lauten. Und die Zahlen hängen dann auch noch davon ab, in welcher Reihenfolge man die Controls hinzugefügt hat.

Ja, ich bin mir bewusst, dass man den Namen explizit vergeben kann, aber der Name ist für mich ein absolutes Implementierungsdetail (letztlich ist es ja ein Variablenname) und nichts, worüber ich ein Control, das sich in einer regelmäßigen Anordnung befindet, tatsächlich "adressieren" wollen würde.

Aber das ist nur mein Empfinden. Funktionieren wird es durchaus auch so. Der Code ist eben nicht sonderlich "wartbar".

0

Was möchtest Du wissen?