Dynamisch viele Textboxen erstellen?

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von SpaceyX.

    Dynamisch viele Textboxen erstellen?

    Hey,

    Ich möchte eine Form haben, in der ich eine unbestimmte Anzahl Benutzereingaben erhalte.
    Aus einer Formel bekomm ich die Anzahl Variablen, die in dieser enthalten sind.
    Daraufhin soll dann ein Fenster aufgehen, in dem genauso viele Labels und Textboxen enthalten sind, wie es Variablen gibt.

    Links soll zum Beispiel in einem Label stehen "Variable x" und rechts soll man diese dann in einer Textbox benennen.
    Die Anzahl der Variablen ist aber erst zur Laufzeit bekannt.
    Was ist der einfachste Ansatz dafür?

    Grüße
    Grüße
    Felix
    Als Beispiel:

    VB.NET-Quellcode

    1. Dim NewTextBox As New TextBox
    2. 'hier alle relevanten Eigenschaften der neuen TextBox einstellen
    3. Me.Controls.Add(NewTextBox)

    Das Ganze lässt sich natürlich auch in einer Schleife abhandeln, in der Du dann auch festlegst, wieviele CEs entstehen sollen.

    VB.NET-Quellcode

    1. Dim NewTextBox As TextBox = Nothing
    2. For i = 0 To 10
    3. NewTextBox = New TextBox
    4. 'hier alle relevanten Eigenschaften der neuen TextBox einstellen
    5. NewTextBox.Top = i * 30 + 20 'z.B.
    6. Me.Controls.Add(NewTextBox)
    7. Next

    oder natürlich auch möglich:

    VB.NET-Quellcode

    1. Dim ListOfNewCEs As New List(Of Control)
    2. Dim NewTextBox As TextBox = Nothing
    3. For i = 0 To 10
    4. NewTextBox = New TextBox
    5. 'hier alle relevanten Eigenschaften der neuen TextBox einstellen
    6. NewTextBox.Top = i * 30 + 20 'z.B.
    7. ListOfNewCEs.Add(NewTextBox)
    8. Next
    9. Me.Controls.AddRange(ListOfNewCEs.ToArray)
    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.

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

    Ist gerade noch so zu vertreten. Ich wollte Dir nämlich eigentlich nach dem genauen Grund fragen, warum Du denn das so benötigst, wie Du meinst. Meistens findet man doch eine ganz passable andere Lösung, die es nicht erfordert, sehr viele Controls darzustellen. Wenn Du magst, dann erzähle mal, was das genaue Vorhaben ist. Wenn nicht, dann möchte ich den Beitrag von @VaporiZed soweit ergänzen, dass Du lieber ein eigenes UserControl erstellst.

    Du hast ja auch von einem Label gesprochen, dass der TextBox vorangestellt werden soll. Sonst erstellst Du 25 TextBoxen und noch dazu 25 Labels. Ausserdem rate ich Dir, die UserControls dann in ein Flow-Layout-Panel zu stecken, so ersparst Du Dir das Hantieren mit den Koordinaten. Aber wirklich schön ist es meist nie, viele Controls auf die From zu klatschen.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Alles klar.
    Das ganze erweist sich damit wirklich nicht als besonders schön.

    Mein Plan sieht so aus:
    In einer anderen Form gibt der Benutzer eine Formel ein, aus der wird die Anzahl der Variablen rausgeholt, und für alle diese Variablen muss dann ein Name/Beschreibung angegeben werden. Ich muss die Eingaben aus der Textbox also irgendwie wieder rauskriegen.

    Und um 25 Textboxen und Labels zu vermeiden, hab ich ja gefragt, ob es da eine angenehmere Lösung gibt.

    Grüße
    Grüße
    Felix
    Ist ein DataGridView evtl. Geeignet für dein Vorhaben?
    "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
    Kombiniert mit einem tDS und die Sache geht mit wenigen Code-Zeilen fast wie von selbst.
    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.
    Das DataGridView läuft.. halbwegs.

    Ich krieg es schon hin, die erste Spalte zu befüllen. Die Benutzereingaben in Spalte 2 werden auch funktionierend abgeholt.

    Eine kleine Frage hab ich aber noch:
    Ich möchte, dass der Benutzer den Dialog nur schliessen kann, wenn Spalte 2 komplett ausgefüllt ist. Ich hab schon das CellValueChanged-Event gefunden, ist das richtig dafür? Und wie kann ich am Besten die Spalte durchgehen?

    Grüße
    Grüße
    Felix

    Kenaex schrieb:

    Ich möchte, dass der Benutzer den Dialog nur schliessen kann, wenn Spalte 2 komplett ausgefüllt ist. Ich hab schon das CellValueChanged-Event gefunden, ist das richtig dafür?
    Natürlich nicht.
    Hör dir mal selbst zu:
    ]Ich möchte, dass der Benutzer den Dialog nur schliessen kann, wenn ...
    Welche Events von welchem Objekt kommen also inFrage?

    Oder noch genauer gefragt (es sind ja 2 Fragen):
    1. Von welchem Objekt (und welchen Datentyp hat dieses)?
    2. Welches Event? (Tipps: a) "schliessen" heisst auf englisch: "close", b) die Events eines Datentyps kann man zB im ObjectBrowser sehr schön nachgucken - aber dazu muss man eben den Datentyp auch wissen)

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

    Da Toteditieren verboten ist, mach ich zumindest nach EdRs Antwort einen Spoiler drum. Erst reinschauen, wenn Du die Antwort glaubst zu kennen ;)
    Spoiler anzeigen

    Solange Du mit einem ungebundenen DGV hantierst, wäre eine Möglichkeit:

    VB.NET-Quellcode

    1. Private Sub Form_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    2. For Each Row As DataGridViewRow In DataGridView1.Rows
    3. If Row.Cells(1).Value Is Nothing Then e.Cancel = True : Exit Sub
    4. Next
    5. End 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.
    Du machst Dir zuviel Arbeit. Ich nehme jetzt an, dass Du die Formel, wie auch immer, auswertest. Das Ergebnis der Auswertung ist, wie Du sagst und wie ich es verstehe, eine Anzahl von Variablen, die der Nutzer benennen, bzw. eine Erklärung dazu abgeben soll.

    So ein Ergebnis könnte evtl. so aussehen:

    VB.NET-Quellcode

    1. Public Class Variable
    2. Public Property VariableSymbol As String
    3. Public Property VariableName As String
    4. Public Property VariableDescription As String
    5. Public Sub New(symbol As String)
    6. Me.VariableSymbol = symbol
    7. End Sub
    8. Public Function Check() As Boolean
    9. Return Me.VariableName <> String.Empty AndAlso Me.VariableDescription <> String.Empty
    10. End Function
    11. End Class


    Ich weiß ja nicht, in wie weit Du Dich mit OOP (Object Oriented Programming) auskennst. Diese Klasse bildet quasi eine Variable ab, die Du aus der Formel erhalten hast. Bei der Erzeugung wird dieser Klasse das Symbol (x, y usw..) übergeben, da diese ja aus der Formel kommt. VariableName und VariableDescription sind vom Benutzer zu ergänzen.

    Du kannst nun eine List(Of Variable) als Datenquelle (DataSource) für Dein DataGridView angeben. Das DataGridView wird dann ohne weiteren Code die Ansicht entsprechend anpassen. Hier der Code für die gesamte Form-Klasse.

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private _v As New List(Of Variable)
    3. Public Sub New()
    4. InitializeComponent()
    5. For i As Integer = 0 To EvaluateFormula() - 1
    6. _v.Add(New Variable("x" & i))
    7. Next
    8. Me.DataGridView1.DataSource = _v
    9. End Sub
    10. Private Function EvaluateFormula() As Integer
    11. Return 2
    12. End Function
    13. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    14. If _v.Where(Function(x) Not x.Check()).Count > 0 Then
    15. MessageBox.Show("Pls fill in all data.")
    16. Else
    17. MessageBox.Show("ok")
    18. End If
    19. End Sub
    20. End Class




    Die Public Sub New() ist nur exemplarisch zu verstehen. Soll meinen, ich erzeuge mir einfach Dummy-Daten. Du müsstest hier dann natürlich die geparsten Daten aus der Formel heranziehen.

    Die Klasse Variable hat außerdem eine Funktion, die prüft, ob VariableName und VariableDescripition ausgefüllt wurden. Die Anwendung kannst Du in der Form-Klasse => Button1_Click in Aktion sehen. Hier könntest Du dann, anstatt eine MessageBox anzuzeigen, entscheiden, ob die Form geschlossen wird oder nicht.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Ich glaub ihr habt mich ein wenig falsch verstanden.. Ich war auf der Suche nach einem Event, dass ausgelöst wird, wenn irgendein Wert bzw. Text im Datagridview geändert wird.

    Außerdem bin ich wohl kein Experte, aber auch nicht so ahnungslos, wie ihr offensichtlich denkt.

    Ich programmiere übrigens in c# :)

    Grüße
    Grüße
    Felix
    Oh, C# auch gut. Aber sollte doch kein Problem sein, das zu überführen. Es geht ja nicht um den Code, sondern um den Sinn, der darin steckt.

    Schade jedenfalls, dass Du nicht auf die Hinweise eingehst, die ich versucht habe zu vermitteln. Viel Erfolg weiterhin!
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Ich hab auch mit Übersetzungen zwischen VB und C# kein Problem :)

    Das stimmt so außerdem garnicht.
    Ich hab jetzt die List<Variable> als DataSource ausgewählt und die Bezeichner werden prima angegeben.

    Wie krieg ich jetzt nach den Benutzereingaben die Inhalte wieder zurück in die List?

    Grüße
    Grüße
    Felix
    Hat mich nur verwirrt, da Du nach einem Event für das Ändern einer DataGridView-Cell gefragt hast. Wenn Du die Liste an das DGV gebunden hast, dann brauchst Du die Inhalte nicht wieder zurückholen, das geht automatisch, sobald Du die in der Zelle Enter drückst, also die Eingabe bestätigst oder die Zelle verlässt und auf etwas anderes klickst.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Ja, danach suche ich auch immernoch

    Ich möchte, dass mein Button solange ​Enabled = false ist, bis alle Beschreibungen "ausgefüllt" sind.

    Oder wie soll ich das umsetzen?
    Es sollen nämlich auf keinen Fall "leere" Beschreibungen ins Spiel kommen

    Grüße
    Grüße
    Felix
    Ahsooo. Also entweder hab ich das überlesen oder Du hast das nicht erwähnt. Hier gibt es bestimmt mehrere Events, die Du dafür nutzen kannst. Aus dem Bauch heraus würde ich das CellEndEdit verwenden und hier abfragen, ob alle Elemente in der Liste Deine Vorgaben erfüllen.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o