Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
650 views
in Technique[技术] by (71.8m points)

c# - Get text from dynamically created textbox in asp.net

I've been banging my head against this all morning, so hopefully I can get some help. Essentially I'm having issues getting values from some textbox controls I'm creating dynamically in .net 4.

Here's the desired flow of the application.

1). User selects a html document from a dropdown menu that is a template for a letter. This html document has tags of the format $VARIABLENAME$ that will be replaced with the correct values.

2). The program runs though the template and pulls out all strings of the format $STRING$ and stores them in a list.

3). For each entry in this list, the program generates an asp:label and an asp:textbox with a unique ID based on the original $VARIABLENAME$ field.

4). User enters replacement values, and hits submit.

5). Program replaces all $STRING$'s with the replacement values and outputs the result.

Everything works well up to the point where I need to get values from the text boxes. I'm quite sure it's an issue with the page lifecycle, but because the textboxes are not being generated until the use selects the desired template from the dropdown, I'm not sure how to make them persist through postbacks so I can reference them.

Am I going about this all wrong? How do I access the text fields created from a dropdown event after a postback froma submitbutton event occurs?

EDIT: Here's the most of the relevant code.

protected void createTextBoxes(List<string> results)
    {
        if (results != null)
        {
            foreach (string result in results)
            {
                string formattedResult = result.Substring(1, result.Length - 2);
                formattedResult = formattedResult.ToLower();
                formattedResult = char.ToUpper(formattedResult[0]) + formattedResult.Substring(1);


                var label = new Label();
                label.ID = formattedResult;
                label.Text = formattedResult + ": ";
                templateFormPlaceholder.Controls.Add(label);

                var textBox = new TextBox();
                textBox.ID = result;
                templateFormPlaceholder.Controls.Add(textBox);
                templateFormPlaceholder.Controls.Add(new LiteralControl("<br />"));

                previewBtn.Visible = true;
            }
        }
    }

protected void templateDD_SelectedIndexChanged(object sender, EventArgs e)
    {
        var templatePath = "";
        if (templateDD.SelectedIndex == 0)
        {
            previewBtn.Visible = false;
        }

        if (templateDD.SelectedIndex == 1)
        {
            templatePath = employeePath;
        }
        else if (templateDD.SelectedIndex == 2)
        {
            templatePath = managerPath;
        }
        List<string> regMatches = FindMatches(templatePath);
        Session["regMatches"] = regMatches;
        createTextBoxes(regMatches);
    }

protected void Page_Init(object sender, EventArgs e)
    {
        if (Session["regMatches"] != null)
        {
            createTextBoxes((List<string>)Session["regMatches"]);
        }
    }

Later on, I'm trying to add the values from these textboxes to a dictionary. Parameters is the name of the dictionary. The key field is the $STRING$, result is what the user entered in the text box.

   protected void previewBtn_Click(object sender, EventArgs e)
    {
        List<string> matchResults = (List<string>)Session["regMatches"];
        Dictionary<string, string> parameters = new Dictionary<string, string>();
        foreach (string result in matchResults)
        {
            TextBox tb = (TextBox)templateFormPlaceholder.FindControl(result);
            parameters.Add(result, tb.Text);
        }

        var template = ReplaceKeys(parameters);
        outputLBL.Text = template;

Here's the .aspx code.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="offerLetter.aspx.cs"     Inherits="templateRegexTesting.offerLetter" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
    <p>
        Which template would you like to use?
    </p>
    <asp:DropDownList ID="templateDD" runat="server" OnSelectedIndexChanged="templateDD_SelectedIndexChanged"
        AutoPostBack="true">
        <asp:ListItem></asp:ListItem>
        <asp:ListItem Value="1">Employee</asp:ListItem>
        <asp:ListItem Value="2">Manager</asp:ListItem>
    </asp:DropDownList>
    <br />
    <asp:PlaceHolder ID="templateFormPlaceholder" runat="server" />
    <div>
        <asp:Button ID="previewBtn" runat="server" Text="Preview" Visible="false" OnClick="previewBtn_Click" />
    </div>
    <div>
        <asp:Label ID="outputLBL" runat="server"></asp:Label>
    </div>
    <br />
</div>
</form>
</body>
</html>

EDIT: I put this in a comment when I figured it out, but I figured I should move it into the question so it is more visible:

Thought I should update this. I feel like a bit of an idiot, but I did manage to get this working. Basically I was assigning the controls an ID equal to the replacement tokens (So ID="$FIRSTNAME$" for example). It didn't even dawn on me that the $'s would cause any issues. When I just changed to the format ID="Firstname" it works perfectly. Thank you for all of the help!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're right, it's all about the page lifecycle. Dynamically created controls must be re-created at the Page_Init stage, in order to exist before the viewstate binding stage. This means that will have to somehow (using the Session, maybe) store how many textboxes you have created on the previous processing to recreate them. Remind to use the same ID and to add them to your control tree (a repeater or something else that you're using).


UPDATE

Let me give you a suggestion: 1. Declare a class attribute of type List<TextBox> (let's call it CreatedTextBoxes)

  1. Declare a method that receives whatever it needs to create the textboxes. This method must not read anything outside of it's scope. It will simply receive some args, create the textboxes and add them to another control (such as a Repeater). Add each textbox created to CreatedTextBoxes

  2. At the dropdown change event, read the option, save it to the Session and call this method

  3. At Page_Init, verify that object at the Session. If it's null or empty, don't do anything. If it has a value, call that same method, passing the same args

  4. When you need to retrieve that from the dynamically created textboxes, use CreatedTextBoxes and not FindControls()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...