簡體   English   中英

無法動態創建文本框並在同一回發中檢索值

[英]Can't create text box dynamically and retrieve value in the same postback

我正在嘗試根據用戶的請求動態創建文本框控件。

問題在於,我無法在同一回發中創建動態文本框並檢索用戶輸入的數字,並使用該數字創建其他文本框。

看來我總是落后一回。

這就是示例中的全部代碼,HTML頁面中沒有其他代碼。

請幫助我解決問題,以便我可以在用戶請求時創建用戶請求的文本框數量。

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

        form1.InnerText = "how many TextBoxes would you like to add?";
        form1.InnerHtml += "<br />";

        TextBox tb = new TextBox();
        tb.ID = "TextBox1";
        tb.Attributes.Add("type", "number");
        tb.Attributes.Add("runat", "server");
        tb.Attributes.Add("min", "1");
        tb.Attributes.Add("max", "5");                
        tb.AutoPostBack = true;
        tb.TextChanged += new EventHandler(textBox_TextChanged);
        form1.Controls.Add(tb);

        if (tb.Text != "")
        {            
            for (int i = 0; i < Convert.ToInt16(tb.Text); i++)
            {
                TextBox tb1 = new TextBox();
                tb1.ID = "newTB" + i.ToString();
                form1.Controls.Add(tb1);
            }     
        }                    
    }

    protected void textBox_TextChanged(object sender, EventArgs e)
    {
    }
}

我嘗試編寫最短和最簡單的代碼,因為我只想弄清楚問題背后的原理,而我找不到足夠類似於我的問題。

好的,因此您的代碼未遵循標准的asp.net編碼慣例。 以下是您要實現的目標的簡單工作示例:

表格代碼

<form id="form1" runat="server">
    <div>
        <asp:Label ID="Label1" runat="server" Text="Label">How many textboxes would you like to create?</asp:Label>
        <asp:TextBox ID="TextBox1" runat="server" AutoPostBack="True" 
            ontextchanged="TextBox1_TextChanged"></asp:TextBox>
        <asp:RangeValidator ID="RangeValidator1" runat="server" 
            ControlToValidate="TextBox1" ErrorMessage="Invalid Number" MaximumValue="5" 
            MinimumValue="1"></asp:RangeValidator>
    </div>
</form>

背后的代碼

protected void Page_Load(object sender, EventArgs e)
    {

    }
    protected void TextBox1_TextChanged(object sender, EventArgs e)
    {
        if (TextBox1.Text != "")
        {
            for (int i = 0; i < Convert.ToInt16(TextBox1.Text); i++)
            {
                TextBox tb1 = new TextBox();
                tb1.ID = "newTB" + i.ToString();
                form1.Controls.Add(tb1);
            }
        }   
    }

我真的建議閱讀asp.net頁面生命周期,並通過一些基本示例來理解基本原理。 教程是一個很好的起點。

編輯-修改 :以下是您遇到的另一個問題,再次需要一點愛和重構(我敢肯定,這樣做可能會有更好的方法!),但是它可以工作。 在我的測試表單中,我有一個提交按鈕,它創建的文本框然后在回發之間“保留”它們的值(但實際上是從“請求”中重新創建它們)。

背后的代碼

protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack)
    {
        foreach (string key in Request.Form)
        {
            if (key.StartsWith("newTB"))
            {
                TextBox tb1 = new TextBox();
                tb1.ID = key;
                tb1.Text = Request.Form[key];
                form1.Controls.Add(tb1);
            }
        }
    }
}

protected void Page_Init(object sender, EventArgs e)
{
    Label label1 = new Label()
        {
            ID = "label1",
            Text = "How many textboxes would you like to create?"
        };

    form1.Controls.Add(label1);

    TextBox textBox1 = new TextBox()
        {
            ID = "TextBox1",
            AutoPostBack = true,
            CausesValidation = true
        };

    textBox1.TextChanged += new EventHandler(TextBox1_TextChanged);

    form1.Controls.Add(textBox1);

    RangeValidator rangeValidator = new RangeValidator()
        {
            ID="RangeValidator1",
            ControlToValidate = "TextBox1",
            MaximumValue = "5",
            ErrorMessage = "Out of range!",
            MinimumValue = "1"
        };

    form1.Controls.Add(rangeValidator);
}

protected void TextBox1_TextChanged(object sender, EventArgs e)
{
    TextBox textBox = form1.FindControl("TextBox1") as TextBox;

    if (Page.IsValid && textBox.Text != "")
    {
        RemoveOldControls();

        for (int i = 0; i < Convert.ToInt16(textBox.Text); i++)
        {
            TextBox tb1 = new TextBox();
            tb1.ID = "newTB" + i.ToString();
            form1.Controls.Add(tb1);
        }
    }
}

//Recursive method to remove all "newTB" textboxes
private void RemoveOldControls()
{
    for (int i = 0; i < form1.Controls.Count; i++)
    {
        if (!string.IsNullOrEmpty(form1.Controls[i].ID) && form1.Controls[i].ID.StartsWith("newTB"))
        {
            TextBox newTextBox = form1.Controls[i] as TextBox;

            if (newTextBox != null)
                form1.Controls.Remove(newTextBox);

            RemoveOldControls();
            break;
        }
    }
}

希望這對您有幫助。

public partial class SomeClass
{
    private TextBox _textBox;
    protected void Page_Init(object sender, EventArgs e)
    {
        _textBox = new TextBox { EnableViewState = true };
        _textBox.TextChanged += (o, args) =>
                                    {

                                    };
        Wrapper.Controls.Add(_textBox);
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        if(!IsPostBack)
        {
            _textBox.Text = "Initial Text";
        }
        else
        {
            // Loaded from viewstate, yay.
        }
    }
}

<asp:Content ID="Content3" ContentPlaceHolderID="ContentPlaceHolderMainContent" runat="server">
    <asp:Panel runat="server" ID="Wrapper"/>
    <asp:Button runat="server" Text="PostBack!"/>
</asp:Content>

您應該始終在Page_Init中添加動態控件。

這是我測試過的:

  • Page_Init,Page_Load中的代碼(在調試中)中斷
  • 已將“初始文本”設置為Page_Load中的文本框。
  • 我將文本更改為“ Initial Text123”
  • 我單擊導致回發的按鈕
  • Page_init,Page_Load,TextChanged處理程序中的代碼(在調試中)中斷。
  • 我可以看到,一旦我進入Page_Load,該文本框就會包含文本“ Initial Text123”,因為它已經從ViewState的值中重新加載了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM