2008-10-17 11 views
13

Tengo problemas para agregar dinámicamente controles dentro de un panel de actualización con devoluciones de elementos parciales. He leído muchos artículos sobre controles dinámicos y entiendo cómo agregarlos y mantenerlos con las devoluciones, pero la mayoría de esa información no se aplica y no funcionará para las devoluciones de datos parciales. No puedo encontrar ninguna información útil sobre cómo agregarlos y mantenerlos con UpdatePanels. Me gustaría hacer esto sin crear un servicio web si es posible. ¿Alguien tiene alguna idea o referencia a alguna información útil?Adición mediante programación de controles de usuario dentro de un UpdatePanel

+0

¿Puede publicar el código con el que intenta hacer esto? –

Respuesta

10

Esto es, creo, uno de los escollos más comunes para los programadores de asp.net pero no es tan difícil hacerlo bien cuando sabes lo que está sucediendo (¡recuerda siempre tu estado de visualización!).

la siguiente pieza de código explica cómo se pueden hacer las cosas. Es una página simple donde un usuario puede hacer clic en un menú que activará una acción que agregará un control de usuario a la página dentro del panel de actualización.
(Este código es prestado from here, y tiene mucha más información con respecto a este tema)

<%@ 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> 

y

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

para el código subyacente.

Eso es básicamente. Puede ver claramente que viewstate se mantiene con LastLoadedControl mientras que los controles se agregan dinámicamente a la página (dentro del panel de actualización (en realidad dentro del placeHolder dentro del panel de actualización) cuando el usuario hace clic en un elemento de menú, que enviará un devolución de datos asincrónica con el servidor

Más información también se puede encontrar aquí:.

y por supuesto en the website that holds the example code que utilicé aquí.

3

Me encontré con el problema de utilizar el método mencionado anteriormente, LoadUserControl() se llama dos veces al manejar un evento. He leído a través de algunos otros artículos y me gustaría mostrar mi modificación:

1) Uso LoadViewState en lugar de Load para cargar el control de usuario:

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

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

2) No se olvide de establecer el Identificación de control al cargar el control de usuario:

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

Prueba esto:

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

puede REPLA ce el contenido de literal con cualquier contenido HTML que desee ...

Cuestiones relacionadas