gpt4 book ai didi

ASP.NET 动态添加控件和页面生命周期

转载 作者:行者123 更新时间:2023-12-04 22:34:10 25 4
gpt4 key购买 nike

我是 ASP.NET 的新手,请多多包涵。

这是我的场景的简化说明。我在页面上有一个按钮。当我单击该按钮时,我将从数据库中检索字符串列表并动态生成一系列链接按钮,并将检索到的字符串作为链接按钮的文本。

我已经明白,出于多种原因,我无法在按钮的单击事件处理程序中执行此操作。我还了解到需要在 Page_Init 或 Page_Load 事件处理程序中生成动态控件,以便连接按钮的点击事件。

所以,这是我考虑的过程:

  1. 点击按钮
  2. 在点击事件处理程序中,检索字符串并将它们存储在 ViewState 变量中
  3. 在 Page_Load 事件处理程序中,遍历 ViewState 变量中的字符串并生成链接按钮

问题在于:由于页面的生命周期,直到 Page_Load 事件之后才会处理按钮的单击事件。因此,在 Page_Load 事件(我希望在其中创建链接按钮)之前,我用于生成链接按钮的字符串不会被检索并分配给 ViewState 变量。

因此,在分配了 ViewState 变量时,直到第二次单击按钮时才会生成链接按钮。显然,这是一个问题。

我设计的解决方案有效,但我不知道它是否是最佳解决方案。这是我正在使用的方法:

  1. 点击按钮
  2. Page_Load 事件触发
  3. 在 Page_Load 事件处理程序中,如果是 PostBack,则检查 ViewState 变量是否为 null 以及哪个控件触发了 PostBack
  4. 如果 ViewState 变量为 null 并且单击了按钮,则检索字符串,将它们保存到 ViewState 变量,并根据 ViewState 变量生成链接按钮
  5. 如果ViewState变量不为空,则根据ViewState变量生成链接按钮

现在,这个解决方案确实有效。但是,如果我刷新页面,我会看到确认表单重新提交弹出窗口(我不喜欢,但我可以接受)。

我对这里的专业程序员的问题是——你们会如何处理我的情况?

更新:

这是一个似乎有效的解决方案。我可能对事件处理程序可以连接到哪里感到困惑,但请看一下这段代码并告诉我它是否有意义或者它是否只是一个 hack:

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
if(ViewState["ControlsArray"] != null)
{
ArrayList controlsList = (ArrayList)ViewState["ControlsArray"];
GenerateLinkButtons(controlsList);
}
}
}

//The event handler for the dynamically generated linkbuttons
void linkButton_Click(object sender, EventArgs e)
{
LinkButton btn = (LinkButton)sender;
string btnName = btn.Text;

Response.Write(btnName);
}

//The click event handler for the Generate Controls button
protected void Button1_Click(object sender, EventArgs e)
{
ArrayList PageArrayList = new ArrayList();

PageArrayList = new ArrayList();
PageArrayList.Add("Text 1");
PageArrayList.Add("Text 2");
PageArrayList.Add("Text 3");
PageArrayList.Add("Text 4");
PageArrayList.Add("Text 5");

GenerateLinkButtons(PageArrayList);

ViewState["ControlsArray"] = PageArrayList;
}

void GenerateLinkButtons(ArrayList controlsList)
{
int i = 1;

foreach (string s in controlsList)
{
LinkButton lnkButton = new LinkButton();
lnkButton.ID = "btn" + i;
lnkButton.Text = s;
this.form1.Controls.Add(lnkButton);
this.form1.Controls.Add(new LiteralControl("<br />"));
lnkButton.Click += new EventHandler(linkButton_Click);
i++;
}
}
}

最佳答案

dynamic controls need to be generated in the Page_Init or Page_Load event handlers so that the link buttons' click events can be wired up.

实际上,您可以在 Button Click 事件上创建控件。但是您必须确保在以下 PostBacks 中重新创建这些控件。

假设您有一个名为 Data 的属性,它指向一个 ViewState 变量。我们还假设您正在使用 Repeater 来创建 LinkBut​​tons。

然后你可以这样做:

private List<string> Data
{
get { return (List<string>)ViewState["Data"]; }
set { ViewState["Data"] = value; }
}

protected void Button_Click(object sender, EventArgs e)
{
Data = GetData();
LoadRepeater();
}

protected void Page_Load(object sender, EventArgs e)
{
if(Data != null)
{
LoadRepeater();
}
}

private void LoadRepeater()
{
repeater.DataSource = Data;
repeater.DataBind();
}

中继器:

<asp:Repeater id="repeater" runat="server">
<ItemTemplate>
<asp:LinkButton id="link" runat="server" OnClick="link_Click" />
</ItemTemplate>
</asp:Repeater>

protected void link_Click(object sender, EventArgs e)
{
//Do Stuff
}

此外,如果您想避免Confirm Form Resubmission,请使用 ASP.NET UpdatePanel 控件。示例:

<asp:UpdatePanel id="upp" runat="server" >
<ContentTemplate>
<!-- Button-->
<!-- Repeater-->
<!-- Other Stuff-->
</ContentTemplate>
</asp:UpdatePanel>

另一种方法(不确定是否有效):

尝试在标签定义上设置转发器数据源:

<asp:Repeater id="repeater" runat="server" DataSource='<%# Data %>' >
<ItemTemplate>
<asp:LinkButton id="link" runat="server" OnClick="link_Click" />
</ItemTemplate>
</asp:Repeater>

protected void Button_Click(object sender, EventArgs e)
{
Data = GetData();
LoadRepeater();
}

protected void Page_Load(object sender, EventArgs e)
{
}

private void LoadRepeater()
{
repeater.DataBind();
}

关于ASP.NET 动态添加控件和页面生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22866656/

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