По сути, в двух словах, проблема в том, что динамически генерируемые триггеры для UpdatePanel больше не могут быть найдены (ASP.NET), как только я добавляю их в качестве дочерних элементов пользовательского элемента управления.
Так какобъем кода, над которым я работаю, довольно существенный. Я воссоздал проблему в меньшем масштабе, что облегчит отладку.
Ошибка, брошенная мне в лицо:
A control with ID 'theTrigger' could not be found for the trigger in UpdatePanel 'updatePanel'.
Я не уверен, является ли эта реализация «пользовательского элемента управления» правильным способом, но я не писал оригинальную реализацию: я работаю с кодом, написаннымпредыдущий разработчик, в который я не могу вносить большие изменения.Это выглядит немного необычно для меня, но, увы, это то, что мне дали.
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestWeb.Default" %>
<!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>
<asp:Panel runat="server" ID="panel">
</asp:Panel>
<asp:ScriptManager ID="scriptManager" runat="server"></asp:ScriptManager>
<asp:UpdatePanel runat="server" ID="updatePanel" UpdateMode="Conditional">
<ContentTemplate>
<asp:Label ID="lblSomething" runat="server"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
Default.aspx.cs
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace TestWeb
{
public partial class Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
UselessTableWrapper table = new UselessTableWrapper();
TableRow tr = new TableRow();
TableCell td = new TableCell();
LinkButton button1 = new LinkButton { ID = "theTrigger", Text = "Click Me" };
button1.Click += button1_Click;
td.Controls.Add(button1);
tr.Controls.Add(td);
table.AddRow(tr);
panel.Controls.Add(table);
// ### uncomment these lines (and comment the one above) to see it working
// ### without the custom control
/*
Table realTable = new Table();
realTable.Controls.Add(tr);
panel.Controls.Add(realTable);
*/
updatePanel.Triggers.Add(new AsyncPostBackTrigger { ControlID = "theTrigger", EventName = "Click" });
scriptManager.RegisterAsyncPostBackControl(button1);
}
protected void button1_Click(object sender, EventArgs e)
{
lblSomething.Text = "Random number: " + new Random().Next(100);
updatePanel.Update();
}
}
}
MyControl.cs
using System;
using System.Web.UI.WebControls;
namespace TestWeb
{
public class UselessTableWrapper : WebControl
{
private Table table = new Table();
protected override void OnPreRender(EventArgs e)
{
Controls.Add(table);
}
public void AddRow(TableRow row)
{
table.Controls.Add(row);
}
}
}
Буду признателен за любые идеи.
Редактировать
Я попытался переключить для этого событие OnPreRender
(найдено вучебник):
protected override void RenderContents(HtmlTextWriter writer)
{
writer.BeginRender();
table.RenderControl(writer);
writer.EndRender();
base.RenderContents(writer);
}
... в надежде, что это исправит, но это не так.