以编程方式在UpdatePanel中添加用户控件

时间:2008-10-17 19:00:37

标签: c# asp.net asp.net-ajax

我在使用部分回发在更新面板中动态添加控件时遇到问题。我已经阅读了很多关于动态控件的文章,我理解如何使用回发添加和维护它们,但大多数信息不适用,不适用于部分回发。我找不到有关使用UpdatePanel添加和维护它们的任何有用信息。如果可能的话,我想在不创建Web服务的情况下这样做。有没有人对某些有用的信息有任何想法或参考?

3 个答案:

答案 0 :(得分:10)

我认为这是asp.net程序员常见的陷阱之一,但实际上并不是很难在你知道发生了什么事情时做到正确(总是记得你的观点!)。

以下代码解释了如何完成任务。这是一个简单的页面,用户可以单击一个菜单,该菜单将触发一个操作,该操作将向更新面板内的页面添加用户控件。
(此代码借用from here,并且有更多关于此主题的信息)

<%@ 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内的placeHolder内)) ,它将向服务器发送异步回发。

更多信息也可以在这里找到:

当然还有the website that holds the example code我在这里使用过。

答案 1 :(得分:3)

我遇到了使用上述方法的问题,处理事件时会调用两次LoadUserControl()。我已经阅读了其他一些文章,并希望向您展示我的修改:

1)使用LoadViewstate而不是Page_Load加载用户控件:

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

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

2)加载usercontrol时不要忘记设置控件ID:

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

答案 2 :(得分:3)

试试这个:

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

您可以将文字内容替换为您想要的任何HTML内容...

相关问题