C# 以编程方式在 UpdatePanel 内添加用户控件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/213429/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Programmatically Adding User Controls Inside An UpdatePanel
提问by angelo
I'm having trouble dynamically adding controls inside an update panel with partial postbacks. I've read many articles on dynamic controls and I understand how to add and maintain them with postbacks but most of that information doesn't apply and won't work for partial postbacks. I can't find any useful information about adding and maintaining them with UpdatePanels. I'd like to do this without creating a web service if it's possible. Does anyone have any ideas or references to some helpful information?
我在带有部分回发的更新面板中动态添加控件时遇到问题。我已经阅读了许多关于动态控件的文章,我了解如何使用回发添加和维护它们,但大部分信息并不适用,也不适用于部分回发。我找不到有关使用 UpdatePanels 添加和维护它们的任何有用信息。如果可能的话,我想在不创建 Web 服务的情况下执行此操作。有没有人对一些有用的信息有任何想法或参考?
采纳答案by sven
This is, I think, one of the common pitfalls for asp.net programmers but isn't actually that hard to get it right when you know what is going on (always remember your viewstate!).
我认为,这是 asp.net 程序员的常见陷阱之一,但当您知道发生了什么时(始终记住您的视图状态!),实际上并没有那么难做到正确。
the following piece of code explains how things can be done. It's a simple page where a user can click on a menu which will trigger an action that will add a user control to the page inside the updatepanel.
(This code is borrowed from here, and has lots more of information concerning this topic)
下面的一段代码解释了事情是如何完成的。这是一个简单的页面,用户可以在其中单击菜单,该菜单将触发一个操作,将用户控件添加到更新面板内的页面。
(这段代码是从这里借来的,有很多关于这个主题的信息)
<%@ 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>
and
和
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();
}
}
for the code behind.
对于后面的代码。
That's basically it. You can clearly see that the viewstate is being kept with LastLoadedControlwhile the controls themselves are dynamically added to the page (inside the updatePanel (actually inside the placeHolder inside the updatePanel) when the user clicks on a menu item, which will send an asynchronous postback to the server.
基本上就是这样。您可以清楚地看到,当用户单击菜单项时,控件本身被动态添加到页面(在 updatePanel 内(实际上在 updatePanel 内的 placeHolder 内)时,viewstate 与LastLoadedControl保持一致,这将发送异步回发)到服务器。
More information can also be found here:
还可以在此处找到更多信息:
- http://aspnet.4guysfromrolla.com/articles/081402-1.aspx
- http://aspnet.4guysfromrolla.com/articles/082102-1.aspx
- http://aspnet.4guysfromrolla.com/articles/081402-1.aspx
- http://aspnet.4guysfromrolla.com/articles/082102-1.aspx
and of course on the website that holds the example codeI used here.
回答by sven
I encountered the problem that using the method mentioned above, LoadUserControl() is called twice when handling an event. I've read through some other articles and would like to show you my modification:
我遇到了使用上面提到的方法,LoadUserControl() 在处理事件时被调用两次的问题。我已经阅读了一些其他文章,并想向您展示我的修改:
1) Use LoadViewstate instead of Page_Load to load the user control:
1) 使用 LoadViewstate 而不是 Page_Load 来加载用户控件:
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
if (!string.IsNullOrEmpty(CurrentUserControl))
LoadDataTypeEditorControl(CurrentUserControl, panelFVE);
}
2) Don't forget to set the control id when loading the usercontrol:
2)不要忘记在加载用户控件时设置控件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;
}
回答by Shoham
Try this:
尝试这个:
Literal literal = new Literal();
literal.Text = "<script type='text/javascript' src='http://www.googleadservices.com/pagead/conversion.js'>";
UpdatePanel1.ContentTemplateContainer.Controls.Add(literal);
You can replace the content of literal with any HTML content you want...
你可以用你想要的任何 HTML 内容替换文字的内容......