Laden...

Daten von einer Dynamischen Textbox?

Erstellt von Sieben vor 15 Jahren Letzter Beitrag vor 15 Jahren 1.455 Views
Sieben Themenstarter:in
140 Beiträge seit 2006
vor 15 Jahren
Daten von einer Dynamischen Textbox?

Hi,

ich hab ein Problem mit einer Dynamischen Textbox.

Ausgangslage:

Ich habe im Designer eine Tabelle angelegt, diese befülle ich im Code-Behind mit TableRows und TableCells. In einer Celle erzeuge ich auch eine Textbox und einen Button, dem ich einen Event zuweise. Die Textbox und der Button werden auch wunderbar im Html angezeigt, wenn ich allerdings auf den Button klicke, komme ich nicht an den Wert der Textbox heran?

Was mache ich falsch?

gruß Sieben

Nur die Kogge schwimmt! 😁

479 Beiträge seit 2008
vor 15 Jahren

Wie wärs, wenn du ein Array, oder eine Dictionary benutzt?

mfg.
markus111

[Follow me on Twitter](http://twitter.com/blendingsky)
S
33 Beiträge seit 2008
vor 15 Jahren

Hallo Sieben,
vielleich hilft Dir das folgende Beispiel weiter:


    protected void Page_Load(object sender, EventArgs e)
    {
        HtmlTable tbl = new HtmlTable();
        tbl.ID = "DynTable";

        for (int i = 0; i < 10; i++)
        {
            HtmlTableRow tr = new HtmlTableRow();

            HtmlTableCell c1 = new HtmlTableCell();
            TextBox txtBox = new TextBox();
            txtBox.ID = String.Format("txtBox{0}", i);
            c1.Controls.Add(txtBox);

            Button btn = new Button();
            btn.Text = String.Format("Button {0}", i);
            btn.ID = String.Format("btn{0}", i);
            btn.Click += new EventHandler(DynBtnClick);
            c1.Controls.Add(btn);

            tr.Cells.Add(c1);            
            tbl.Rows.Add(tr);
        }

        this.form1.Controls.Add(tbl);
    }

    void DynBtnClick(object sender, EventArgs e)
    {
        Button btn = (Button)sender;
        TextBox txtBox = (TextBox)this.form1.FindControl(String.Format("txtBox{0}", btn.ID.Remove(0,3)));
        
        string tmp = txtBox.Text;
    }

5.941 Beiträge seit 2005
vor 15 Jahren

Hallo Sieben

Du solltest die Controls so früh wie möglich (OnInit), spätestens in (OnLoad) hinzufügen und das immer.

Wenn du keine Referenz auf deinen Button hast, kannst du <Control>.FindControl(<ID>) benutzen.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

Sieben Themenstarter:in
140 Beiträge seit 2006
vor 15 Jahren

Hi ihr 3,

erstmal danke für die Antworten. Ich konnte am Wochenende leider nix machen, deswegen schreib ich erst jetzt.

Ich baue die Tabelle mit den Controls genauso auf wie Syst3m es geschrieben hat. Also in der Page_Load per Methoden Aufruf.

Wenn ich die Textbox dynamisch hinzufüge, muss ich dann immer mit FindControls arbeiten? Wenn ich die Textbox, per Designer ( VS 2008 ) auf die '*.aspx' Datei ziehe dann kann ich sie ja im Codebehind direkt als Member ansprechen?
Geht das auch wenn ich die Textbox dynamisch hinzufüge, quasi wenn ich sie zum Member der Klasse machen?

FindControls hatte ich schon probiert, da hat er keine Textbox gefunden? Liegt das an einer falschen ID?
Den zweiten Parameter von FindControls versteh ich nicht?

Ich werde heut abend nochmal das FindControl probieren.

Nochmal kurz zu meinem Vorhaben:
Auf einer Aspx Seite sollen eine Textbox + Button angezeigt werden. In die Textbox kann man eine Zahl eingeben. Je nachdem welche Zahl man eingegeben hat, sollen auf dieser Seite in einer Schleife weitere Dynamische Controls erzeugt werden.

gruß Sieben

Nur die Kogge schwimmt! 😁

3.003 Beiträge seit 2006
vor 15 Jahren

Wenn ich die Textbox dynamisch hinzufüge, muss ich dann immer mit FindControls arbeiten? Wenn ich die Textbox, per Designer ( VS 2008 ) auf die '*.aspx' Datei ziehe dann kann ich sie ja im Codebehind direkt als Member ansprechen?

Die zwei Fragen hängen zusammen. Beim Ziehen im Designer wird dein Control als Member der Klasse, in der der Code-Behind steht, automatisch generiert. Steht dann in der .designer.cs-Datei. Wenn du sie also nicht im Designer auf die Seite ziehst, wird auch keine Membervariable erzeugt. Das solltest du dann also von Hand nachholen.

Solltest du einfach Controls.Add() benutzen, ohne eine Membervariable zu benutzen, ist es irgendwo in der Hierarchie der Controls noch vorhanden. Dann kannst du es mit FindControl ebenso referenzieren. Bequemer ist natürlich:


class mypage
{
   protected Control m_MyTextBox;
   protected override void OnInit(...)
   {
      m_MyTextBox = new Textbox();
      Page.Controls.Add(m_MyTextBox);
   }
}

Auf einer Aspx Seite sollen eine Textbox + Button angezeigt werden. In die Textbox kann man eine Zahl eingeben. Je nachdem welche Zahl man eingegeben hat, sollen auf dieser Seite in einer Schleife weitere Dynamische Controls erzeugt werden.

Dann ist es wohl wenig sinnvoll, für jedes Control ein Member anzulegen, du weißt ja nicht, wieviele es werden. Mach eine Membervariable, die ein Array von Controls darstellt:


protected List<Control> m_AddedControls;
protected override void OnInit(EventArgs e)
{
   m_AddedControls = new List<Control>();
   for(int i = 0; i < irgendwas; i++)
   {
       Control newControl = new Textbox();
       m_AddedControls.Add(newControl);
       Page.Controls.Add(newControl);
    }
}

Was zu welchem Event passiert auf einer ASP-Seite ist auch recht interessant. Zweite Tabelle auf dieser Seite:
http://msdn.microsoft.com/en-us/library/ms178472.aspx

Gruß,

LaTino
EDIT: deutschmodul im Eimer, wie es aussieht.

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

Sieben Themenstarter:in
140 Beiträge seit 2006
vor 15 Jahren
  
class mypage  
{  
   protected Control m_MyTextBox;  
   protected override void OnInit(...)  
   {  
      m_MyTextBox = new Textbox();  
      Page.Controls.Add(m_MyTextBox);  
   }  
}  
  

Wenn ich das so mache, dann speichert die Textbox keine Werte. Wenn ich per Button den Event auslöse, ist der eingegebene Wert der Textbox weg?!

Bei jedem Seitenaufruf wird auch immer ein neues Textbox Objekt angelegt? Das kann es ja auch nicht sein, ist ja klar das der Wert dadurch verloren geht?!

Genau das passiert ja im Designermodus nicht, dort behält die Textbox ihren Wert nach dem Buttonklick?

gruß Sieben

Nur die Kogge schwimmt! 😁

Sieben Themenstarter:in
140 Beiträge seit 2006
vor 15 Jahren

Ich hab jetzt mal eine ganz einfache Seite gemacht.

Dort habe ich eine Textbox im Codebehind erzeugt und sie dort per 'form1.Controls.Add (...)' hinzugefügt. Dort funktioniert sie auch so wie sie soll 😃

Bei der anderen Seite funktioniert es leider immer noch nicht.

Ausganglage:

Es ist eine 'WebContentForm'. Auf dieser habe ich per Designer eine 'Asp.Table' mit der 'ID=LayoutTable' hinzugefügt:


  <asp:Table ID="LayoutTable" runat="server">
  </asp:Table>

Dieser füge ich dann im Codebehind 'MakeLayout ()' mehrere Rows und Cells hinzu:


    TextBox m_ctrlTextbox;

    protected void Page_Load ( object sender, EventArgs e )
    {
      m_ctrlTextbox = new TextBox ();
    }

    protected void MakeLayout ()
    {
      LayoutTable.CssClass = "VxBetTable";

      {
        TableRow  Row       = GetStdTblRow  ();
        TableCell Cell1     = GetStdTblCell ();

        Label   lblText     = new Label     ();
        Button  btnOnChange = new Button    ();

        lblText .Text = "Anzahl Spiele: ";

        m_txtGames.MaxLength = 2;
        m_txtGames.Width     = 20;

        btnOnChange.Text = "Ändern";

        btnOnChange.Click += new EventHandler ( btnOnChange_Click );

        Cell1.ColumnSpan = 5;

        Cell1.Controls.Add ( lblText       );
        Cell1.Controls.Add ( m_ctrlTextbox );
        Cell1.Controls.Add ( btnOnChange   );

        Row.Cells.Add ( Cell1 );

        LayoutTable.Rows.Add ( Row );
      }

      {
        TableRow  Row   = GetStdTblRow ();

        Row.CssClass = "VxBetRow";

        TableCell Cell1 = GetStdTblCell ();
        TableCell Cell2 = GetStdTblCell ();
        TableCell Cell3 = GetStdTblCell ();
        TableCell Cell4 = GetStdTblCell ();
        TableCell Cell5 = GetStdTblCell ();

        Cell1.Text = "Datum";
        Cell2.Text = "&nbsp;";
        Cell3.Text = "Heimteam";
        Cell4.Text = "&nbsp;";
        Cell5.Text = "Auswärtsteam";

        Row.Cells.Add ( Cell1 );
        Row.Cells.Add ( Cell2 );
        Row.Cells.Add ( Cell3 );
        Row.Cells.Add ( Cell4 );
        Row.Cells.Add ( Cell5 );

        LayoutTable.Rows.Add ( Row );
      }

      {
        for ( int nIndex = 0; nIndex < m_Games; nIndex++ )
        {
          TableRow  Row   = GetStdTblRow ();

          Row.CssClass = "VxBetRow";

          TableCell Cell1 = GetStdTblCell ();
          TableCell Cell2 = GetStdTblCell ();
          TableCell Cell3 = GetStdTblCell ();
          TableCell Cell4 = GetStdTblCell ();
          TableCell Cell5 = GetStdTblCell ();

          //----------------------------------------------------------------------

          Calendar Cal = new Calendar ();

          DropDownList ddlHomeTeam = new DropDownList ();
          DropDownList ddlAwayTeam = new DropDownList ();

          for ( int nJndex = 0; nJndex < m_TeamList.Count; nJndex++ )
          {
            TeamItem Item = m_TeamList [ nJndex ];

            ddlHomeTeam.Items.Add ( Item.TeamName );
            ddlAwayTeam.Items.Add ( Item.TeamName );
          }

          //----------------------------------------------------------------------

          TextBox txtDay   = new TextBox ();
          TextBox txtMonth = new TextBox ();
          TextBox txtYear  = new TextBox ();
          Label   lbl1     = new Label ();
          Label   lbl2     = new Label ();

          txtDay.MaxLength = 2;
          txtDay.Width = 20;
          txtMonth.MaxLength = 2;
          txtMonth.Width = 20;
          txtYear.MaxLength = 4;
          txtYear.Width = 40;

          lbl1.Text = ".";
          lbl2.Text = ".";

          Cell1.Controls.Add ( txtDay );
          Cell1.Controls.Add ( lbl1 );
          Cell1.Controls.Add ( txtMonth );
          Cell1.Controls.Add ( lbl2 );
          Cell1.Controls.Add ( txtYear );
          Cell2.Text = "::";
          Cell3.Controls.Add ( ddlHomeTeam );
          Cell4.Text = "-";
          Cell5.Controls.Add ( ddlAwayTeam );

          Row.Cells.Add ( Cell1 );
          Row.Cells.Add ( Cell2 );
          Row.Cells.Add ( Cell3 );
          Row.Cells.Add ( Cell4 );
          Row.Cells.Add ( Cell5 );

          LayoutTable.Rows.Add ( Row );

        }
      }

      {
        TableRow Row = GetStdTblRow ();

        TableCell Cell = GetStdTblCell ();

        Cell.HorizontalAlign = HorizontalAlign.Right;
        Cell.ColumnSpan = 5;

        Button BtnOnSend = new Button ();

        BtnOnSend.Text = "Speichern";

        Cell.Controls.Add ( BtnOnSend );

        Row.Cells.Add ( Cell );

        LayoutTable.Rows.Add ( Row );
      }
    }

Mein Problem ist nach wie vor, das ich nicht auf die Controls, die ich in 'MakeLayout ()' erzeuge und der 'LayoutTable' hinzufüge, zugreifen kann? Die besagte Textbox ist momehtan ein Member der Klasse heißt 'm_ctrlTextBox' und wird in 'Page_Load' instanziiert.

Der Unterschied zu meinem ersten Beispiel ist zweifelsohne, das ich die Textbox dort der 'form1' dirket zuweise?

Müsste nicht die 'LayoutTable' automatisch von Asp einer Form zugewiesen werden? Es ist ja eine ContentPage? Zudem mit dem Attribut 'runat=Server'?

gruß Sieben

Nur die Kogge schwimmt! 😁

Sieben Themenstarter:in
140 Beiträge seit 2006
vor 15 Jahren

Man ich bin einfach zu blöd!!!

Man sollte schon in die richtige Methode schauen schäm


protected void btnOnChange_Click ( Object Sender, EventArgs e )
{
  String Str = m_ctrlTextbox.Text; // Hier wird der Text richtig angezeigt

  int k = 4711;
}

In der Eventhandler Methode hat die Textbox natürlich den gesuchten Wert. Ich habe immer in die 'Page_Load' Methode rein debuggt.

Das heißt ja:
1.ASP ruft zuerst die 'Page_Load' Methode auf -> Instanzierung aller Controls.
2. Dann füllt ASP alle Controls mit bekannter ID mit Werten aus dem Response.
3. Event-Methode wird aufgerufen

???

Wenn das so ist, dann hab ich allerdings ein Problem: Denn in 'MakeLayout' die von 'Page_Load' aufgerufen wird, benötigt den Wert aus der 'TextBox' um das dynamische Layout zu designen?? 😦

gruß Sieben

Nur die Kogge schwimmt! 😁

3.003 Beiträge seit 2006
vor 15 Jahren

Erstmal super, dass du den Link mit dem lifecycle gelesen hast 🙂. Zweitens ist dein Problem vermutlich so alt wie....hm, wie irgendwas altes.

Jetzt lies die Seite nochmal.

-> Wann werden die Controls erzeugt? Wann solltest du also dein Control auch erzeugen?

-> Wann werden die Controls mit Werten gefüllt? Wann solltest du das machen?

http://msdn.microsoft.com/en-us/library/ms178472.aspx (2. Tabelle)

Logisch: wenn das "Event" btnClick eintritt, ist Page_Load (nur ein Wrapper für OnLoad) bereits durch. Aber ich denke, jetzt findest du selber raus, wie es weiter geht 🙂.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

5.941 Beiträge seit 2005
vor 15 Jahren

Hallo Latino

(nur ein Wrapper für OnLoad) bereits durch.

Ein implizit angehängter Eventhandler für das Load-Event und OnLoad ist die auslösende Methode 😃

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

3.003 Beiträge seit 2006
vor 15 Jahren

Genau. Ich sollte auch schreiben, was ich meine 😉.
Wollte schon immer mal ausprobieren, ob Page_Load wirklich nicht mehr aufgerufen wird, wenn man im override der OnLoad keinen base-Aufruf macht. Jetzt ist es soweit. IMO hat sich MS mit diesen massenhaften impliziten Codegenerierungen bis hin zu den Memberdeklarationen aus dem Designer heraus keinen Gefallen getan. Macht das alles nur undurchschaubarer.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

5.941 Beiträge seit 2005
vor 15 Jahren

Hallo LaTino

Naja, das muss man natürlich wissen.
Von alleine löscht sich der Base-Aufruf nicht.
Und die die das nicht wissen, überschreiben OnLoad eher nicht 😉

Ich bin kein Freund von AutoEventWireup aber die Generierung der Memberdeklaratinen möchte ich in WebForms nicht missen.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011

Sieben Themenstarter:in
140 Beiträge seit 2006
vor 15 Jahren

Ok Livecycle hin und Livecycle her, das Problem bleibt trotzdem bestehen 😦

Ich hab jetzt mal die 'OnLoadComplete' Methode überschrieben um mein Layout zu machen. Das Problem dabei ist, das alle Controls die ich in der 'OnLoadComplete' hinzugefügt habe, ihre Werte nicht mehr speichern. Nur die Controls die vor der 'OnLoadComplete' 'Livecyclehierachie' geadded wurden behalten ihre Werte?

Zur Veranschaulichung: Grün eingekreist sind die vor 'OnLoadComplete' hinzugefügten Controls rot eingekreist die nach 'OnLoadComplete'.

Nur die Kogge schwimmt! 😁

5.941 Beiträge seit 2005
vor 15 Jahren

Hallo Sieben

Es ist eigentlich alles gesagt.
Hier noch ein paar sehr gute Links wenn es um dynamische Controls geht:

Dort empfehle ich auch, dass es meistens einfacher geht und das es ein komplexes Thema ist, das man nicht einfach so mal schnell im Forum abhandeln kann.

Gruss Peter

--
Microsoft MVP - Visual Developer ASP / ASP.NET, Switzerland 2007 - 2011