- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我最近不得不重新处理网络表单代码,并在尝试更新显示调查回复列表的现有页面时遇到了问题。
我有一个 ListView 显示已回答调查的人的详细信息。当您单击行中的图标时,该行将进入编辑模式并将其信息(姓名、电子邮件等)显示为输入框。
到目前为止一切顺利,现在我需要为该调查和那个人添加问题和答案。将它们写出来很容易,但是当回发发生时,该行返回到 ItemTemplate 并且控件消失了。
我知道对于动态控件,您应该在 Page_Init 中创建,以便 webforms 可以重新绑定(bind)它们,但这里的控件直到 ListItem ItemEditing 事件才创建,并且数据保存在 ItemUpdating 事件中。
我一直在思考如何在生命周期的正确时间点使用正确的数据在正确的位置使用正确的控件。现在我正在尝试从 Request.Form 中提取值,但是使用 CheckboxList 很难弄清楚已选择的内容。
编辑:应该实际运行的新示例
<%@ 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>
然后是后面的代码:
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,
}
最佳答案
如果没有看到您的代码,很难给出完整的答案,但基本上您需要在回发时重新创建控件树,包括动态创建的控件。
例如,您可以在 Page_Load 事件处理程序中执行此操作。
您可以存储在 ViewState 中重新创建控件树所需的任何数据,以便它在 PostBack 上可用。
我不确定你的意思:
... when the postback happens the row goes back to the ItemTemplate
我希望 EditIndex 在回发后保持不变,除非您明确修改它,因此编辑行保持不变,并使用 EditItemTemplate。
如果您可以发布一个简化的示例来说明您的问题,我(或其他人)可能会提供进一步的帮助。
更新
根据发布的代码,您需要在 ItemUpdating 事件处理程序中重新创建动态控件,并按照您在 ItemEditing 事件处理程序中创建它们的顺序将它们添加到控件树中。 IE。您可能需要重复代码:
var questionPannel = lL.Items[e.ItemIndex].FindControl("lead_table") as HtmlTable;
var campaignQuestionsTableRow = questionPannel.FindControl("campaign_questions") as HtmlTableRow;
var questions = GetQuestions();
foreach(var question in questions)
{
// This builds a WebControl for the dynamic question
var control = CreateQuestionControl(question);
campaignQuestionsTableRow.AddControl(control);
}
更新 2
更新时,需要重新创建 PostBack 上的动态控件。将您的 Page_Load 事件处理程序更改为类似以下内容:
protected void Page_Load(object sender, EventArgs e)
{
LV.DataSource = Leads;
LV.DataBind();
if (IsPostBack)
{
if (LV.EditIndex >= 0)
{
var leadLabel = (Label)LV.Items[LV.EditIndex].FindControl("lblLeadID");
var leadID = int.Parse(leadLabel.Text);
var panel = (Panel)LV.Items[LV.EditIndex].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));
}
}
}
}
在第一个 Postback(单击“编辑”)上,EditIndex 将为 -1,动态控件在 OnItemEditing 处理程序中创建。
在第二次回传(单击更新)上,EditIndex 将是您正在编辑的行的索引,您需要在 Page_Load 中重新创建动态控件。如果这样做,您将在到达 OnItemUpdating 事件处理程序时找到发布的值。
虽然我认为了解如何以这种方式使用动态控件是值得的,但在生产应用程序中,我可能会按照 Elisheva Wasserman 的建议在 EditItemTemplate 中使用 Repeater。 Repeater 可以包含一个 UserControl,它封装了根据问题类型隐藏/显示 UI 元素的逻辑。
关于c# - 如何在回发时从 ListView 中的动态控件获取值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30784635/
这个问题在这里已经有了答案: final keyword in method parameters [duplicate] (9 个回答) 关闭 8 年前。 在此示例中,声明 Object fina
我的目标:是通过我的函数更新字段获取选定值并使用函数输出值运行它。 问题:当我从列表中选择值时,它不会触发函数,也不会更新字段。 感谢您的帮助。 HTML 12 14 16 18 20 22 24
我有一本具有这种形式的字典: myDict = {'foo': bar, 'foobar baz': qux} 现在,我想拆分字典键中的空格,使其成为下一个键并获取值(重复)。 myDictRev1
vector a; vector b; int temp_holder; cout > temp_holder) a.push_back(temp_holder); cout > temp_h
Java 的开发过程中免不了与 Date 类型纠缠,准备总结一下项目经常使用的日期相关操作,JDK 版本 1.7,如果能够帮助大家节约那么几分钟起身活动一下,去泡杯咖啡,便是极好的,嘿嘿。当然,我
我正在使用 jquery ui 日期选择器来获取 fromDate 和 toDate 以下是from日期的代码 $("#from_date").datepicker({
我是一名优秀的程序员,十分优秀!