I recently had to go back to working with web form code and there was a problem trying to update an existing page that shows a list of survey responses.
I have a ListView showing the details of the people who responded to the survey. When you click on the icon in the line, the line of which enters the editing mode and displays your information (name, email address, etc.) as input fields.
So far so good, now I need to add questions and answers for this survey and this person. Writing them is easy, but when the postback occurs, the string returns to the ItemTemplate and the controls go away.
I know with the help of dynamic controls that you must create in Page_Init, so web forms can reassemble them, but here the controls are not created until the ListEtem ItemEditing event and the data stored in the ItemUpdating event.
I focused on how I can make controls in the right place with the right data at the right point in the life cycle. Right now I'm trying to pull the values ββfrom Request.Form, but with CheckboxList it's hard to understand what was selected.
Edit: A new example that should actually run
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="QuestionExample.aspx.cs" Inherits="QuestionExample" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <table> <asp:ListView runat="server" ID="LV" OnItemEditing="LV_OnItemEditing" OnItemUpdating="LV_OnItemUpdating"> <LayoutTemplate> <tr> <td><asp:PlaceHolder runat="server" ID="itemPlaceHolder"></asp:PlaceHolder></td> </tr> </LayoutTemplate> <ItemTemplate> <asp:LinkButton ID="EditButton" runat="server" CommandName="Edit" Text="Edit"/> ID: <asp:Label runat="server" ID="lblLeadID" Text="<%# ((Lead)Container.DataItem).LeadID %>" /> Name: <%# ((Lead)Container.DataItem).Name %><br/> </ItemTemplate> <EditItemTemplate> <asp:LinkButton ID="UpdateButton" runat="server" CommandName="Update" Text="Update" /> ID: <asp:Label runat="server" ID="lblLeadID" Text="<%# ((Lead)Container.DataItem).LeadID %>" /> <asp:Label runat="server">Name</asp:Label> <asp:TextBox runat="server" id="tbName" Text="<%# ((Lead)Container.DataItem).Name %>"></asp:TextBox> <asp:Panel runat="server" id="pnlQuestions"></asp:Panel> </EditItemTemplate> </asp:ListView> </table> </form> </body> </html>
Then the code is behind:
using System; using System.Collections.Generic; using System.Linq; using System.Web.UI; using System.Web.UI.WebControls; public partial class QuestionExample : Page { #region fake data protected List<Question> Questions = new List<Question>() { new Question { QuestionID = 0, QuestionType = QuestionType.Textbox, QuestionText = "TextBox", Options = null }, new Question { QuestionID = 1, QuestionType = QuestionType.DropDownList, QuestionText = "DDL", Options = new List<string> { "A", "B", "C"} }, }; protected List<Lead> Leads = new List<Lead> { new Lead { LeadID = 0, Name = "Bob", Answers = new Dictionary<string, string> { { "TextBox", "Hi" }, { "DDL", "B" } } }, new Lead { LeadID = 1, Name = "Fred", Answers = new Dictionary<string, string> { { "TextBox", "Stuff" }, { "DDL", "C" } } }, }; #endregion protected void Page_Load(object sender, EventArgs e) { LV.DataSource = Leads; LV.DataBind(); } protected void LV_OnItemEditing(object sender, ListViewEditEventArgs e) { LV.EditIndex = e.NewEditIndex; LV.DataBind(); var leadLabel = (Label)LV.Items[e.NewEditIndex].FindControl("lblLeadID"); var leadID = int.Parse(leadLabel.Text); var panel = (Panel)LV.Items[e.NewEditIndex].FindControl("pnlQuestions"); var lead = Leads.First(l => l.LeadID == leadID); foreach (var answer in lead.Answers) { var question = Questions.First(q => q.QuestionText == answer.Key); panel.Controls.Add(CreatQuestionControl(question, lead, true)); } } protected Control CreatQuestionControl(Question question, Lead lead, bool setAnswers) { Control result = null; switch (question.QuestionType) { case QuestionType.Textbox: var tb = new TextBox(); if (setAnswers) { var answer = lead.Answers[question.QuestionText]; tb.Text = answer; } result = tb; break; case QuestionType.DropDownList: var ddl = new DropDownList { DataSource = question.Options }; ddl.DataBind(); if (setAnswers) { var answer = lead.Answers[question.QuestionText]; ddl.SelectedValue = answer; } result = ddl; break; } return result; } protected void LV_OnItemUpdating(object sender, ListViewUpdateEventArgs e) { // Get input data here somehow LV.EditIndex = -1; } } public class Lead { public int LeadID { get; set; } public string Name { get; set; } public Dictionary<string, string> Answers { get; set; } } public class Question { public int QuestionID { get; set; } public string QuestionText { get; set; } public QuestionType QuestionType { get; set; } public List<string> Options { get; set; } } public enum QuestionType { Textbox = 0, DropDownList = 1, }