Программное Добавление Пользовательских Элементов Управления Внутри UpdatePanel

У меня возникли проблемы с динамическим добавлением элементов управления внутри панели обновления с частичными обратными связями. Я прочитал много статей о динамических элементах управления, и я понимаю, как добавлять и поддерживать их с обратными связями, но большая часть этой информации не применяется и не будет работать для частичных обратных связей. Я не могу найти никакой полезной информации о добавлении и поддержании их с помощью UpdatePanels. Я хотел бы сделать это без создания веб-сервиса, если это возможно. У кого-нибудь есть идеи или ссылки на некоторые полезная информация?

3 ответов


Это, я думаю, одна из распространенных ловушек для asp.net программисты, но на самом деле это не так сложно, когда вы знаете, что происходит (всегда помните свое viewstate!).

следующий фрагмент кода объясняет, как это можно сделать. Это простая страница, где пользователь может нажать на меню, которое вызовет действие, которое добавит пользовательский элемент управления на страницу внутри updatepanel.
(Этот код заимствован отсюда, и имеет много больше информация, касающаяся данной темы)

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="SampleMenu1.aspx.cs" Inherits="SampleMenuPage1" %>
<!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>Sample Menu</title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:Menu ID="Menu1" runat="server" OnMenuItemClick="Menu1_MenuItemClick">
            <Items>
                <asp:MenuItem Text="File">
                    <asp:MenuItem Text="Load Control1"></asp:MenuItem>
                    <asp:MenuItem Text="Load Control2"></asp:MenuItem>
                    <asp:MenuItem Text="Load Control3"></asp:MenuItem>
                </asp:MenuItem>
            </Items>
        </asp:Menu>
        <br />
        <br />
        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
            <ContentTemplate>
                <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
            </ContentTemplate>
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="Menu1" />
            </Triggers>
        </asp:UpdatePanel>
    </form>
</body>
</html>

и

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class PlainSampleMenuPage : System.Web.UI.Page
{
    private const string BASE_PATH = "~/DynamicControlLoading/";

    private string LastLoadedControl
    {
        get
        {
            return ViewState["LastLoaded"] as string;
        }
        set
        {
            ViewState["LastLoaded"] = value;
        }
    }

    private void LoadUserControl()
    {
        string controlPath = LastLoadedControl;

        if (!string.IsNullOrEmpty(controlPath))
        {
            PlaceHolder1.Controls.Clear();
            UserControl uc = (UserControl)LoadControl(controlPath);
            PlaceHolder1.Controls.Add(uc);
        }
    }

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

    protected void Menu1_MenuItemClick(object sender, MenuEventArgs e)
    {
        MenuItem menu = e.Item;

        string controlPath = string.Empty;

        switch (menu.Text)
        {
            case "Load Control2":
                controlPath = BASE_PATH + "SampleControl2.ascx";
                break;
            case "Load Control3":
                controlPath = BASE_PATH + "SampleControl3.ascx";
                break;
            default:
                controlPath = BASE_PATH + "SampleControl1.ascx";
                break;
        }

        LastLoadedControl = controlPath;
        LoadUserControl();
    }
}

для кода.

это в основном все. Вы можете ясно видеть, что отображение ведется с LastLoadedControl в то время как сами элементы управления динамически добавляются на страницу (внутри updatePanel (фактически внутри заполнителя внутри updatePanel) , когда пользователь нажимает на пункт меню, который отправит асинхронную обратную передачу в сервер.

более подробную информацию можно найти здесь:

и конечно веб-сайт, который содержит пример кода Я здесь.


я столкнулся с проблемой, что с помощью метода, упомянутого выше, LoadUserControl () вызывается дважды при обработке события. Я прочитал некоторые другие статьи и хотел бы показать вам свою модификацию:

1) Используйте LoadViewstate вместо Page_Load для загрузки пользовательского элемента управления:

protected override void LoadViewState(object savedState)
{
    base.LoadViewState(savedState);

    if (!string.IsNullOrEmpty(CurrentUserControl))
        LoadDataTypeEditorControl(CurrentUserControl, panelFVE);
}

2) Не забудьте установить идентификатор элемента управления при загрузке usercontrol:

private void LoadDataTypeEditorControl(string userControlName, Control containerControl)
{
    using (UserControl myControl = (UserControl) LoadControl(userControlName))
    {
        containerControl.Controls.Clear();

        string userControlID = userControlName.Split('.')[0];
        myControl.ID = userControlID.Replace("/", "").Replace("~", "");
        containerControl.Controls.Add(myControl);
    }
    this.CurrentUserControl = userControlName;
}

попробуйте это:

Literal literal = new Literal();
literal.Text = "<script type='text/javascript' src='http://www.googleadservices.com/pagead/conversion.js'>";
UpdatePanel1.ContentTemplateContainer.Controls.Add(literal);

вы можете заменить содержимое литерала любым HTML-контентом, который вы хотите...