Получить текст из динамически созданного текстового поля в 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
)
Объявите метод, который получает все необходимое для создания текстовых полей. Этот метод не должен читать что-либо вне его области действия. Он просто получит некоторые аргументы, создаст текстовые поля и добавит их в другой элемент управления (например,
Repeater
). Добавить каждое текстовое поле, созданное дляCreatedTextBoxes
В выпадающем списке изменений прочитайте опцию и сохраните ее в
Session
и вызвать этот методВ
Page_Init
проверьте этот объект наSession
, Если он нулевой или пустой, ничего не делайте. Если он имеет значение, вызовите тот же метод, передавая те же аргументы- Когда вам нужно извлечь это из динамически созданных текстовых полей, используйте
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
}
}
}