Получить текст из динамически созданного текстового поля в asp.net

Я бился головой об это все утро, так что, надеюсь, я смогу помочь. По существу, у меня проблемы с получением значений из некоторых элементов управления текстовым полем, которые я создаю динамически в.net 4.

Вот желаемый поток приложения.

1). Пользователь выбирает HTML-документ из выпадающего меню, который является шаблоном для письма. Этот HTML-документ содержит теги формата $VARIABLENAME$, которые будут заменены правильными значениями.

2). Программа запускается через шаблон и извлекает все строки в формате $STRING$ и сохраняет их в списке.

3). Для каждой записи в этом списке программа генерирует метку asp:label и asp:text с уникальным идентификатором на основе исходного поля $VARIABLENAME$.

4). Пользователь вводит заменяющие значения, а хиты отправляют.

5). Программа заменяет все $STRING$ на значения замены и выводит результат.

Все работает хорошо до того момента, когда мне нужно получить значения из текстовых полей. Я совершенно уверен, что это проблема жизненного цикла страницы, но поскольку текстовые поля не генерируются до тех пор, пока пользователь не выберет нужный шаблон из выпадающего списка, я не уверен, как заставить их сохраняться с помощью обратных передач, чтобы я мог ссылаться на них.

Я все об этом ошибаюсь? Как получить доступ к текстовым полям, созданным из выпадающего события после того, как произошло событие обратной передачи?

РЕДАКТИРОВАТЬ: Вот большая часть соответствующего кода.

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"]);
        }
    }

Позже я пытаюсь добавить значения из этих текстовых полей в словарь. Параметры - это название словаря. Ключевое поле - это $STRING$, результат - то, что пользователь ввел в текстовое поле.

   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;

Вот код.aspx.

<%@ 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>

РЕДАКТИРОВАТЬ: я положил это в комментарии, когда я понял это, но я решил, что я должен переместить это в вопрос, чтобы он был более заметным:

Я думал, что я должен обновить это. Я чувствую себя немного идиотом, но мне удалось заставить это работать. По сути, я назначал элементам управления идентификатор, равный токенам замены (например, ID="$FIRSTNAME$"). Меня даже не осенило, что $ вызовет какие-либо проблемы. Когда я только что перешел на формат ID = "Имя", он работает отлично. Спасибо за всю помощь!

3 ответа

Решение

Вы правы, это все о жизненном цикле страницы. Динамически созданные элементы управления должны быть воссозданы на Page_Init этап, чтобы существовать до этапа привязки viewstate. Это значит, что придется как-то (используя Sessionможет быть) запомни сколько textboxes вы создали на предыдущей обработке, чтобы воссоздать их. Напомните, чтобы использовать тот же идентификатор и добавить их в дерево управления (ретранслятор или что-то еще, что вы используете).


ОБНОВИТЬ

Позвольте мне дать вам предложение: 1. Объявить атрибут класса типа List<TextBox> (давайте назовем это CreatedTextBoxes)

  1. Объявите метод, который получает все необходимое для создания текстовых полей. Этот метод не должен читать что-либо вне его области действия. Он просто получит некоторые аргументы, создаст текстовые поля и добавит их в другой элемент управления (например, Repeater). Добавить каждое текстовое поле, созданное для CreatedTextBoxes

  2. В выпадающем списке изменений прочитайте опцию и сохраните ее в Session и вызвать этот метод

  3. В Page_Initпроверьте этот объект на Session, Если он нулевой или пустой, ничего не делайте. Если он имеет значение, вызовите тот же метод, передавая те же аргументы

  4. Когда вам нужно извлечь это из динамически созданных текстовых полей, используйте CreatedTextBoxes и не FindControls()

Вы добавляете TextBox controls to templateFormPlaceholder.Controls но использовать form1.FindControl найти их. FindControl method will find a control only if the control is directly contained by the specified container - from http://msdn.microsoft.com/en-us/library/486wc64h.aspx. Попробуйте позвонить templateFormPlaceholder.FindControl вместо.

Создайте динамические текстовые поля и добавьте их на панель asp, чтобы вы могли легко получить к ним доступ.

Вот элементы дизайна ASP.NET.

<div class="form-group">
<asp:Panel ID="panel" runat="server" CssClass="form-group">

</asp:Panel>
</div>

Код C# для генерации динамических текстовых полей

 protected void create_dynamic_text(object sender, EventArgs e)
{
    int num = 5; // you can give the number here
    for (int i = 0; i < num;i++ )
    {
        TextBox tb = new TextBox();
        tb.ID = "txt_box_name" + i.ToString();
        tb.CssClass = "add classes if you need";
        tb.Width = 400; //Manage width and height 
        panel.Controls.Add(tb); //panel is my ASP.Panel object. Look above for the design code of ASP panel
    }
}

Код C# для принятия значений

 protected void reade_values(object sender, EventArgs e)
{
   int num=5; // your count goes here
    TextBox tb = new TextBox();
        for (int i = 0; i < num; i++)
        {
           tb=(TextBox)panel.FindControl("txt_box_name"+i.ToString());
           string value = tb.Text; //You have the data now
        }
    }
}
Другие вопросы по тегам