0

基本上,简而言之,问题在于,一旦我将 UpdatePanel 动态生成的触发器添加为自定义控件的子项,就无法再找到它们(通过 ASP.NET)。

由于我正在处理的代码量相当大,我已经在较小的范围内重新创建了问题,这将使调试更容易。

我脸上抛出的错误是:

A control with ID 'theTrigger' could not be found for the trigger in UpdatePanel 'updatePanel'.

我不确定“自定义控件”的这种实现是否是正确的方法,但我没有编写原始实现:我正在使用以前的开发人员编写的代码,我无法对其进行大量修改. 这对我来说看起来有点不寻常,但是,唉,这就是我得到的。

默认.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>

默认.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();
      }
   }
}

我的控制.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);
}

...希望它会解决它,但它没有。

4

1 回答 1

1

这是我从后面的代码加载 ascx Web 控件到 aspx 控件中所采用的方法。

在控制中:

namespace dk_admin_site.Calculations
{
    public partial class AssignedFieldCalculation : System.Web.UI.UserControl
    {
        public static AssignedFieldCalculation LoadControl(Calculation initialData)
        {
            var myControl = (AssignedFieldCalculation) ((Page) HttpContext.Current.Handler).LoadControl(@"~\\Calculations\AssignedFieldCalculation.ascx");
            myControl._initialData = initialData;
            return myControl;
        }

        private Calculation _initialData;
        public Calculation Data { get { return _initialData; } }
        protected void Page_Load(object sender, EventArgs e) {}
    }
}

在后面的 web 表单代码中:

protected void Page_Load(object sender, EventArgs e)
{

    if (this.IsPostBack)
    {
        if (ScriptManager1.AsyncPostBackSourceElementID.StartsWith("ctl00$MainContent$calc") && ScriptManager1.AsyncPostBackSourceElementID.EndsWith("$btnRemoveCalculationFromField"))
        {
            //do something on the postback
        }
        else if (ScriptManager1.AsyncPostBackSourceElementID.StartsWith("ctl00$MainContent$calc") && (ScriptManager1.AsyncPostBackSourceElementID.EndsWith("$btnMoveCalculationUp") || ScriptManager1.AsyncPostBackSourceElementID.EndsWith("$btnMoveCalculationDown")))
        {
            //do something on the postback
        }
    }


    foreach (Calculation calc in calculationCollection)
    {
        AssignedFieldCalculation asCalc = AssignedFieldCalculation.LoadControl(calc);
        asCalc.ID = "calc" + calc.UniqueXKey;
        pnlFieldCalculations.Controls.Add(asCalc);

        foreach (Control ct in asCalc.Controls)
        {
            if (ct.ID == "btnMoveCalculationDown" || ct.ID == "btnMoveCalculationUp" || ct.ID == "btnRemoveCalculationFromField")
            {
                ScriptManager1.RegisterAsyncPostBackControl(ct);
            }
        }
    }
}

需要注意的几点:
在将每个控件 ID 添加到 asp:Panel(称为 pnlFieldCalculations)时,您需要使每个控件 ID 唯一。LoadControl 方法允许您传递初始参数

于 2011-04-21T11:36:14.033 回答