Benutzer mit den meisten Antworten
Ein Array von Steuerelementen erzeugen

Frage
-
Hallo zusammen,
mit Dim a as ... kann man jedes beliebige Objekt deklarieren.
Das müsste doch auch mit Arrays gehen. Dim a() as ....
Ich möchte ein Array von Steuerelementen gleicher Klasse erzeugen, damit ich später
indiziert darauf zugreifen kann.
Folgendes Beispiel:
public class form1 ' ein array field der Klasse Label deklarieren: Dim fields() As System.Windows.Forms.Label ' geht Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load ' die erste Instanz von fields erzeugen Dim fields = New System.Windows.Forms.Label() ' geht ' Eigenschaften von fields setzen von default_Label der gleichen Klasse ' fields = default_Label ' geht 'jetzt fields mit Eigenschaften versehen und zwar X und Y Position 'dazu einen Typ xyloc erzeugen: Dim xyloc As System.Drawing.Point = New System.Drawing.Point() ' und mit Werten versehen: xyloc.X = 30 xyloc.Y = 100 Jetzt Steuerelement fields mit Koordinaten versehen Dim i As Integer = 0 fields(i).Location = xyloc ' Ende der Vorstellung 'Fehler 1 Die Klasse "System.Windows.Forms.Label" kann nicht indiziert werden, da sie keine 'Standardeigenschaft hat. end sub end class
Frage: Wie bekomme ich das hin?
Gruß
Ellen
Antworten
-
Hallo Ellen,
statt einem Array, empfiehlt sich eine List(Of T). Das ist aber nicht der Grund, dass Dein Vorhaben scheitert. Der liegt darin, dass Du innerhalb von Form_Load eine lokale Variable "fields" deklariert, die Vorrang vor der Klassenvariable fields() hat, solange Du nicht das Schlüsselwort "Me" voranstellst. Also "Me.fields(x) = ...".
Scope in Visual Basic
http://msdn.microsoft.com/en-us/library/1t0wsc67.aspx
Anbei ein Beispiel mit List(Of T):
Public Class Form1 ' ein array field der Klasse Label deklarieren: Dim fields As List(Of System.Windows.Forms.Label) Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load ' Liste initialisieren: fields = New List(Of System.Windows.Forms.Label) ' Eigenschaften von fields setzen von default_Label der gleichen Klasse ' fields.Add(default_Label) 'jetzt fields mit Eigenschaften versehen und zwar X und Y Position 'dazu einen Typ xyloc erzeugen: Dim xyloc As System.Drawing.Point = New System.Drawing.Point(30, 100) ' Jetzt Steuerelement fields mit Koordinaten versehen Dim i As Integer = 0 fields(i).Location = xyloc End Sub End Class
Thorsten Dörfler
Microsoft MVP Visual Basic- Als Antwort vorgeschlagen Robert BreitenhoferModerator Freitag, 6. November 2009 15:07
- Als Antwort markiert Ellen Ramcke Mittwoch, 19. Mai 2010 14:42
-
Hallo Ellen,
Du erzeugst ja keine zweite Instanz, sondern arbeitest generell mit der vom Designer erzeugten Instanz Deines Labels. Eine neue Instanz erzeugst Du über das Schlüsselwort "New":
Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load ' Berechnung der Koordinaten Dim xyloc As System.Drawing.Point = New System.Drawing.Point() xyloc.X = RichTextBox_RX.Left xyloc.Y = RichTextBox_RX.Top + RichTextBox_RX.Height + Ydiff fields = New List(Of System.Windows.Forms.Label) For i As Integer = 0 To 5 xyloc.Y += 50 * i Dim lbl = New System.Windows.Forms.Label() lbl.Location = xyloc lbl.Text = String.Format("Label {0}", i) Me.Controls.Add(lbl) fields.Add(lbl) Next End Sub
Thorsten Dörfler
Microsoft MVP Visual Basic- Als Antwort markiert Ellen Ramcke Mittwoch, 19. Mai 2010 14:43
Alle Antworten
-
Hallo Ellen,
statt einem Array, empfiehlt sich eine List(Of T). Das ist aber nicht der Grund, dass Dein Vorhaben scheitert. Der liegt darin, dass Du innerhalb von Form_Load eine lokale Variable "fields" deklariert, die Vorrang vor der Klassenvariable fields() hat, solange Du nicht das Schlüsselwort "Me" voranstellst. Also "Me.fields(x) = ...".
Scope in Visual Basic
http://msdn.microsoft.com/en-us/library/1t0wsc67.aspx
Anbei ein Beispiel mit List(Of T):
Public Class Form1 ' ein array field der Klasse Label deklarieren: Dim fields As List(Of System.Windows.Forms.Label) Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load ' Liste initialisieren: fields = New List(Of System.Windows.Forms.Label) ' Eigenschaften von fields setzen von default_Label der gleichen Klasse ' fields.Add(default_Label) 'jetzt fields mit Eigenschaften versehen und zwar X und Y Position 'dazu einen Typ xyloc erzeugen: Dim xyloc As System.Drawing.Point = New System.Drawing.Point(30, 100) ' Jetzt Steuerelement fields mit Koordinaten versehen Dim i As Integer = 0 fields(i).Location = xyloc End Sub End Class
Thorsten Dörfler
Microsoft MVP Visual Basic- Als Antwort vorgeschlagen Robert BreitenhoferModerator Freitag, 6. November 2009 15:07
- Als Antwort markiert Ellen Ramcke Mittwoch, 19. Mai 2010 14:42
-
Hallo Thorsten,
so funktioniert es jetzt.
Ein Fehler ist noch da. Wenn ich die 2te Instanz zur Liste hinzufüge, wird nur noch das 2te Steuerelement in der Form angezeigt.
Das erste ist unsichtbar. Entferne ich die Anweisungen zur zweiten Instanz, wird wieder das erste Element angezeigt.
Es sollen 2 Label in der Form zur Anzeige kommen im Abstand Y von 50 Pixel und X = 30 vom linken Rand der Form.
Label_Time ist mit dem Formdesigner erzeugt. Alle Label sollen diese Eigenschaften haben. (gleich aussehen)
Hier der Code.
(Der Aufbau der Elemente wird später in einer Loop erfolgen. Das hier ist nur zum Test.)
Gruß
Ellen
Public Class Form1__CC Const Ydiff As Integer = 30 Dim fields As List(Of System.Windows.Forms.Label) Dim xstart As Integer Dim ystart As Integer ' --------------------------------------------------------------- ' Windows form aufbauen '--------------------------------------------------------------- Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load ' Berechnung der Koordinaten Dim xyloc As System.Drawing.Point = New System.Drawing.Point() xyloc.X = RichTextBox_RX.Left xyloc.Y = RichTextBox_RX.Top + RichTextBox_RX.Height + Ydiff fields = New List(Of System.Windows.Forms.Label) Dim i As Integer = 0 'erste Instanz erzeugen fields.Add(Label_Time) fields(i).Location = xyloc fields(i).Text = "1111" Me.Controls.Add(fields(i)) 'zweite Instanz erzeugen i = 1 fields.Add(Label_Time) xyloc.Y += 50 fields(i).Location = xyloc fields(i).Text = "2222" Me.Controls.Add(fields(i)) End Sub end class
-
Hallo Ellen,
Du erzeugst ja keine zweite Instanz, sondern arbeitest generell mit der vom Designer erzeugten Instanz Deines Labels. Eine neue Instanz erzeugst Du über das Schlüsselwort "New":
Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load ' Berechnung der Koordinaten Dim xyloc As System.Drawing.Point = New System.Drawing.Point() xyloc.X = RichTextBox_RX.Left xyloc.Y = RichTextBox_RX.Top + RichTextBox_RX.Height + Ydiff fields = New List(Of System.Windows.Forms.Label) For i As Integer = 0 To 5 xyloc.Y += 50 * i Dim lbl = New System.Windows.Forms.Label() lbl.Location = xyloc lbl.Text = String.Format("Label {0}", i) Me.Controls.Add(lbl) fields.Add(lbl) Next End Sub
Thorsten Dörfler
Microsoft MVP Visual Basic- Als Antwort markiert Ellen Ramcke Mittwoch, 19. Mai 2010 14:43
-
Hallo Thorsten,
ich möchte mein Feedback geben.
Es läuft jetzt, wie ich es mir vorgestellt habe.
Ich habe das aufgearbeitet und fasse zusammen:
1.) Class List(Of T)
Da wäre ich allein nicht drauf gekommen. Wie schön, dass es Foren gibt.
Ich lese täglich in der Msdn Library und finde Sachen, welche man irgendwann
gebrauchen kann. Die Library ist mächtig. Für einen Anfänger ist es sehr schwer
da zurecht zufinden. Den anderen geht es wohl genauso.
2.) fields() und fields
Ich habe das tatsächlich 2mal deklariert. In der Methode und in der Klasse.
Deswegen hat der Compiler zunächst auch nicht gemeckert.
Mein Fehler. Jetzt habe ich es verstanden.
3.) fields = default_Label
Auf beiden Seiten steht der gleiche Typ. Deswegen funktioniert diese Anweisung auch.
Nur damit erzeuge ich keine neue Instanz. Die Instanz wird nach fields kopiert und nur
diese ausgeführt. Das Element default_Label verschwindet zur Laufzeit von der Form.
4.) Me.fields und fields
Me referenziert auf die aktuelle Klasse und fields lokal auf die Methode.
Aber nur dann, wenn auch lokal definiert. Sonst geht der Verweis zurück auf die
Klasse. Den Fehler machen wohl viele. Habe ich hier schon einmal gesehen.
5.) fields.Add(Label_Time)
Siehe meinen Code (black & white). Mit dem Debugger kann man nachvollziehen, dass
tatsächlich 2 Listeneinträge entstehen. Wenn Du die genau betrachtest, sind sie absolut
identisch, nämlich Label_Time. Auch die Handles sind identisch. Was heist das? Es ist keine
neue Instanz enstanden, sondern eine Kopie. Und nur diese( die letzte) wird auch ausgeführt.
Wenn ich die Zeile
fields.Add(Label_Time) ersetze mit dieser:
fields.Add(New System.Windows.Forms.Label) geht es.
Die Eigenschaften von Label_Time müssen in einzelnen Anweisungen
nach fields kopiert werden. Dann haben die neuen erzeugten Label auch das gleiche Aussehen.
Das ist im Prinzip auch das, was Du vorgeschlagen hast.
6.) Objektorientierung
Dieses ist ein schönes Beispiel wie man aus seinem "Lieblings" Steuerelement auch eine
Klasse erzeugen könnte von der die anderen(children) dessen Eigenschaften erben.
Das kommt später dran. Soweit bin ich noch nicht.
Vielen Dank und schöne Grüße
Ellen
- Als Antwort markiert Ellen Ramcke Samstag, 7. November 2009 20:06
- Tag als Antwort aufgehoben Ellen Ramcke Donnerstag, 20. Mai 2010 19:29