Триггер для UpdatePanel исчезает при добавлении в «пользовательский элемент управления» - PullRequest
0 голосов
/ 08 декабря 2010

По сути, в двух словах, проблема в том, что динамически генерируемые триггеры для 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);
}

... в надежде, что это исправит, но это не так.

1 Ответ

1 голос
/ 21 апреля 2011

Это подход, который я использовал при загрузке веб-элемента управления ascx внутри элемента управления 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) {}
    }
}

в веб-формекод позади:

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

Несколько замечаний:
Вам необходимо сделать каждый идентификатор элемента управления уникальным при добавлении его в asp: Panel (называемую pnlFieldCalculations).Метод LoadControl позволяет передавать начальные аргументы

...