2008-10-17 4 views
13

업데이트 게시판에 부분 포스트 백이있는 컨트롤을 동적으로 추가하는 데 문제가 있습니다. 동적 컨트롤에 대한 많은 기사를 읽었으며 포스트 백을 사용하여 추가하고 유지하는 방법을 이해하지만 대부분의 정보는 적용되지 않으며 부분 포스트 백에는 작동하지 않습니다. UpdatePanels를 사용하여 추가 및 유지 관리에 대한 유용한 정보를 찾을 수 없습니다. 가능하다면 웹 서비스를 만들지 않고이 작업을하고 싶습니다. 누구든지 유용한 정보에 대한 아이디어 나 참고 사항이 있습니까?프로그래밍 방식으로 UpdatePanel 내부에 사용자 정의 컨트롤 추가

+0

당신이 이것을하려고하는 코드를 게시 할 수 있습니까? –

답변

10

이것은 asp.net 프로그래머에게 흔히있는 함정 중 하나이지만 실제로 무슨 일이 일어나고 있는지 항상 알기는 어렵지 않습니다 (항상 viewstate를 기억하십시오!).

다음 코드는 어떻게 수행되는지 설명합니다. 이 페이지는 사용자가 updatepanel 내부 페이지에 사용자 정의 컨트롤을 추가하는 동작을 트리거하는 메뉴를 클릭 할 수있는 간단한 페이지입니다.
(이 코드는 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(); 
    } 
} 

.

그건 기본적으로. viewstate가 LastLoadedControl으로 유지되는 것을 명확하게 볼 수 있습니다. 사용자가 메뉴 항목을 클릭 할 때 updatePanel (실제로는 updatePanel 내부의 placeHolder 내부)에서 컨트롤 자체가 페이지에 동적으로 추가됩니다. 서버에 비동기 포스트

더 자세한 정보는 여기에서 찾을 수 있습니다.

그리고 물론 여기에 사용 된 the website that holds the example code입니다.

3

위에서 언급 한 메서드를 사용하면 이벤트 처리시 LoadUserControl()이 두 번 호출되는 문제가 발생했습니다. 좀 다른 기사를 읽은 당신에게 내 수정 보여 드리고자합니다 :

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

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

2)를 설정하는 것을 잊지 마십시오

1) 대신를 Page_Load의 사용 LoadViewstate은 사용자 컨트롤을로드하기를 컨트롤 ID는 해당 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; 
} 
3

이 시도 :

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

당신은 repla 수 당신이 원하는 모든 HTML 콘텐츠로 리터럴의 내용을 유지하십시오 ...

관련 문제