gpt4 book ai didi

c# - 如何在回发时从 ListView 中的动态控件获取值?

转载 作者:太空狗 更新时间:2023-10-29 21:27:16 24 4
gpt4 key购买 nike

我最近不得不重新处理网络表单代码,并在尝试更新显示调查回复列表的现有页面时遇到了问题。

我有一个 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com