开发者

Trigger for UpdatePanel disappearing when added to a "custom control"

开发者 https://www.devze.com 2023-01-29 05:18 出处:网络
Basically, in a nutshell, the problem is that dynamically generated triggers for an UpdatePanel can no longer be found (by ASP.NET) as soon as I add them as children of a custom control.

Basically, in a nutshell, the problem is that dynamically generated triggers for an UpdatePanel can no longer be found (by ASP.NET) as soon as I add them as children of a custom control.

Since the amount of code I'm working on is quite substantial I've recreated the problem on a smaller scale, which will make it easier to debug.

The error thrown in my face is:

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

I'm not sure whether this implementation of a "custom control" is the right way to go about it, but I did not write the original implementation: I'm working with code written by a previous developer to which I cannot make large modifications. It looks a little unusual to me, but, alas, this is what I've been given.

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);
      }
   }
}

Any ideas would be greatly appreciated.

Edit

I've tried switching the OnPreRender event for this (found in a tutorial):

protected override void RenderContents(HtmlTextWriter writer)
{
   writer.BeginRender();
   table.RenderControl(writer);
   writer.EndRender();
   base.RenderContents(writer);
}

... hoping that it would fix it, but it does not.


this is the approach that I've taken with loading a ascx web control inside an aspx control from the code behind.

In the control:

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) {}
    }
}

in the web form code behind:

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);
            }
        }
    }
}

A few things to note:
You need to make each control ID unique when adding it to the asp:Panel (called pnlFieldCalculations). The LoadControl method allows you to pass initial arguments

0

精彩评论

暂无评论...
验证码 换一张
取 消