VisualStudio Arrays |
kein_plan unregistriert
|
|
Meine Frage:
Hallo,
ich möchte in VisualStudio folgendes machen:
Ich habe eine Windows-Forms-Anwendung gestartet und dort mehrere Textboxen erstellt (insgesamt 81 Stück). Jetzt möchte ich die Texte in diesen Textboxen auslesen und in ein Array schreiben.
Wie kann ich das am schnellsten machen?
Ich könnte natürlich schreiben:
code: |
1:
2:
3:
4:
5:
|
int[] Array = new int[81];
Array[0] = Convert.ToInt32(textBox1.Text);
Array[1] = Convert.ToInt32(textBox2.Text);
...
Array[80] = Convert.ToInt32(textBox81.Text); |
|
Aber das ist ja ewig lange Tipperei. Außerdem müsste ich auch noch jedes mal abfragen, ob die Textbox leer ist, sodass ich dann auf ca. 400 Codezeilen kommen würde. Gibt es da noch eine bessere Möglichkeit?
Meine Ideen:
|
|
21.06.2014 10:51 |
|
|
as_string
Haudegen
Dabei seit: 06.11.2013
Beiträge: 638
Herkunft: Heidelberg
|
|
Hallo!
Ich habe leider keine Ahnung von Windows-Forms und auch keine von C# (das ist C#-Syntax, oder), aber zwei Dinge dazu trotzdem:
Du deklarierst ein int-Array. Warum int? Du willst doch offenbar Strings speichern.
So was kann man eigentlich nur besser machen, wenn man die Text-Boxen schon als Array definiert. Irgendwann werden die doch angelegt (ich vermute allerdings, das wird Code sein, den Visual Studio und nicht Du selbst geschrieben hast...) Da kann man ja statt einzelner Variablen textBox1, textBox2... sicherlich auch schon ein Array von 81 Textboxen anlegen und entsprechend initialisieren. Dann ist es nämlich nachher einfach, alle diese Textboxen auch wieder über eine Schleife abzuarbeiten.
Ansonsten könnte es auch sein, dass Windows-Forms die Möglichkeit bietet, ein Array (oder eine Liste) aller registrierten Textboxen zu liefern. Dann hättest Du auch wieder so ein Array, allerdings wären dann wirklich alle Textboxen drin, auch wenn Du in Zukunft noch eine dazu machst. Ob Du das immer willst, ist die andere Frage, und dann wieder zu versuchen, die passenden auszufiltern, ist sicherlich auch nicht die beste Lösung.
Gruß
Marco
|
|
21.06.2014 11:31 |
|
|
as_string
Haudegen
Dabei seit: 06.11.2013
Beiträge: 638
Herkunft: Heidelberg
|
|
|
21.06.2014 11:33 |
|
|
|
Bei 81 TextBoxen muss ich gerade an Sudoku denken, da könnte man auch ein zweidimensionales Array von TextBoxen zur Laufzeit erzeugen.
Noch etwas mehr Code:
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
|
private TextBox[] createTextBoxes()
{
TextBox[] tb = new TextBox[81];
for (int i = 0; i < 81; i++)
{
tb[i] = new TextBox();
tb[i].Name = "textBox" + (i + 1).ToString();
tb[i].Text = (i + 1).ToString();
tb[i].Top = 30 * (i / 9 + 1);
tb[i].Left = 60 * (i % 9 + 1);
tb[i].Width = 50;
tb[i].Parent = this;
}
return tb;
}
private int[] readTextBoxes(TextBox[] tb)
{
int[] array = new int[tb.Length];
for (int i = 0; i < array.Length; i++)
int.TryParse(tb[i].Text, out array[i]);
return array;
}
private int[] readTextBoxes()
{
int[] array = new int[1];
foreach(Control c in this.Controls)
if (c is TextBox)
{
int index;
int.TryParse(c.Name.Substring("textBox".Length), out index);
if (array.Length <= index)
Array.Resize(ref array, index);
int.TryParse(c.Text, out array[index - 1]);
}
return array;
} |
|
__________________ Syntax Highlighting fürs Board (Link)
|
|
21.06.2014 15:16 |
|
|
kein_plan unregistriert
|
|
Zitat: |
Original von as_string
Du deklarierst ein int-Array. Warum int? Du willst doch offenbar Strings speichern.
|
Ich wandle dann beim Einlesen die Strings in int-Zahlen um.
Zitat: |
Original von eulerscheZahl
Bei 81 TextBoxen muss ich gerade an Sudoku denken |
Richtig gedacht.
Vielen Dank, du hast mir sehr geholfen (und sehr viel Schreibkram erspart).
Noch ein paar Fragen:
code: |
1:
|
int.TryParse(tb[i].Text, out array[i]); |
|
liest also den Text in der Textbox tb[i], wandelt diesen in eine int-Zahl um und schreibt das dann in array[i], richtig?
Ich möchte abfragen, ob eine Textbox leer ist; und wenn ja, irgendwelche Anweisungen ausführen. Kann ich dazu statt Zeile 21 folgendes schreiben?
code: |
1:
2:
3:
4:
|
if(!int.TryParse(tb[i].Text, out array[i]))
{
irgendwelche Anweisungen
} |
|
Zu Zeile 12: Was hat
code: |
1:
|
tb[i].Parent = this; |
|
zu bedeuten?
Und den Sinn der letzten Methode private int[] readTextBoxes() habe ich auch nicht wirklich verstanden. Wozu ist die da und was macht die?
Wär nett, wenn du mir da nochmal helfen könntest.
Viele Grüße
|
|
22.06.2014 10:20 |
|
|
|
Zitat: |
int.TryParse(tb[i].Text, out array[i]); liest also den Text in der Textbox tb[i], wandelt diesen in eine int-Zahl um und schreibt das dann in array[i], richtig? |
richtig
Zitat: |
Ich möchte abfragen, ob eine Textbox leer ist; und wenn ja, irgendwelche Anweisungen ausführen. Kann ich dazu statt Zeile 21 folgendes schreiben? |
schon wieder richtig.
tb[i].Parent = this;
bewirkt, dass die TextBox auf this, also vermutlich deiner Windows Form platziert werden. Wenn du den Code ohne diese Zeile ausführst, existieren die TextBoxen zwar, der Nutzer kann sie aber nicht sehen.
Zitat: |
Und den Sinn der letzten Methode private int[] readTextBoxes() habe ich auch nicht wirklich verstanden. Wozu ist die da und was macht die? |
Marco hat ja bereits erwähnt, dass man entweder die TextBoxen zur Laufzeit erzeugen kann, was das auslesen vereinfacht - oder über die vorhandenen Controls iterieren.
Der einfachere Weg ist sicher readTextBoxes(TextBox[] tb). Hier musst du dir keine Gedanken mehr machen, wie du an die TextBoxen kommst, du übergibst sie ja an die Funktion.
Wenn das Kind aber schon in den Brunnen gefallen ist (die die Boxen alle mit der Maus in den Designer gezogen hast), kannst du den Inhalt mit readTextBoxes() trotzdem noch auslesen. Brauchst du aber nicht, wenn du die Erzeugung zur Laufzeit machst.
Oder eben gleich als zweidimensionales Array:
code: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
|
private TextBox[,] createSudokuField()
{
TextBox[,] tb = new TextBox[9, 9];
for (int x = 0; x < 9; x++)
for (int y = 0; y < 9; y++)
{
tb[x, y] = new TextBox();
tb[x, y].Name = "textBox" + y.ToString() + "_" + x.ToString();
tb[x, y].Text = "tb" + y.ToString() + "_" + x.ToString();
tb[x, y].Top = 30 * (y + 1);
tb[x, y].Left = 60 * (x + 1);
tb[x, y].Width = 50;
tb[x, y].Parent = this;
}
return tb;
} |
|
__________________ Syntax Highlighting fürs Board (Link)
|
|
22.06.2014 10:53 |
|
|
kein_plan unregistriert
|
|
OK. Danke euch beiden.
|
|
22.06.2014 16:31 |
|
|
kein_plan unregistriert
|
|
Es sind doch noch Fragen aufgetaucht:
Die Funktion createSudokuField() rufe ich so auf:
code: |
1:
2:
3:
4:
5:
|
public Form1()
{
InitializeComponent();
createSudokuField();
} |
|
Dieses gibt ja ein Array zurück, das ich natürlich auch speichern kann. Wie kann ich dieses Array dann der Funktion readTextBoxes(TextBox[] tb) übergeben (denn das Array existiert ja erstmal nur in public Form1())?
Und die Funktion readTextBoxes(TextBox[] tb) soll erst beim Klicken eines Buttons ausgeführt werden.
Ich könnte ja ein globales Array definieren und da dann den Rückgabewert von createSudokuField() schreiben, aber globale Variablen sollen doch eigentlich vermieden werden, oder?
Außerdem wollte ich bei den Textboxen die Werte in Font und ändern, z.B.:
code: |
1:
2:
3:
|
tb[x, y].Font.Bold = true;
oder
tb[x, y].Font.Size = 15; |
|
Da kommt dann aber die Fehlermeldung: "Einer Eigenschaft oder einem Indexer 'System.Drawing.Font.Bold' kann nichts zugewiesen werden - sie sind schreibgeschützt".
Irgendwie muss man doch diese Eigenschaften ändern können...
|
|
22.06.2014 21:02 |
|
|
|
globale Variablen sollte man vermeiden, wenn man sie nicht unbedingt braucht, aber ich würde nicht soweit gehen, prinzipiell von der Verwendung abzuraten. Hier halte ich es für vertretbar, spontan fällt mir dazu auch keine Alternative ein.
Versuche für die Schrift das hier:
tb[x, y].Font = new Font("Times New Roman", 16, FontStyle.Bold | FontStyle.Italic);
__________________ Syntax Highlighting fürs Board (Link)
|
|
22.06.2014 21:48 |
|
|
|