2009-08-22 3 views
2

다음 코드가 있습니다. 각 단계에 대한 컨트롤을 동적으로로드하는 사용자 정의 컨트롤을 동적으로로드하는 마법사 유형의 인터페이스를 만들려고합니다. 각 단계에는 이벤트를 발생시키는 버튼이 있습니다. 상위 페이지는 마법사의 다음 컨트롤을로드해야합니다. 동일한 컨트롤이 두 번 연속으로 렌더링되어 버튼을 두 번 클릭하게됩니다.마법사에서 동적으로로드 된 컨트롤

코드를 보려면 눈이 필요합니다.

public partial class CreateTriviaGame : BasePage 
    { 
     private TriviaGame _game; 
     private int _step = 1; 

     protected void Page_PreLoad(object sender, EventArgs e) 
     { 
      LoadStepControl(); 
     } 

     private void LoadStepControl() 
     {   
      BaseTriviaGameControl ctrl = null; 
      switch (_step) 
      { 
       case 1: 
        ctrl = (BaseTriviaGameControl)LoadControl("AddEditGame.ascx"); 
        break; 
       case 2: 
        ctrl = (BaseTriviaGameControl)LoadControl("CrudQuestions.ascx"); 
        ctrl.TriviaGame = _game; 
        break; 
       case 3: 
        ctrl = (BaseTriviaGameControl)LoadControl("AddEditPaymentInfo.ascx"); 
        ctrl.TriviaGame = _game; 
        break; 
       case 4: 
        ctrl = (BaseTriviaGameControl)LoadControl("ConfirmPayment.ascx"); 
        ctrl.TriviaGame = _game; 
        break; 
       case 5: 
        ctrl = (BaseTriviaGameControl)LoadControl("ThankForPayment.ascx"); 
        ctrl.TriviaGame = _game; 
        break; 
      } 

      ctrl.EntitySaved += new EventHandler(ctrl_EntitySaved); 
      holder1.Controls.Add(ctrl); 

     } 

     protected void ctrl_EntitySaved(object sender, EventArgs e) 
     { 
      _game = ((BaseTriviaGameControl)sender).TriviaGame; 
      _step++; 
      holder1.Controls.Clear(); 
      LoadStepControl(); 
     } 

     protected override void LoadViewState(object savedState) 
     { 
      base.LoadViewState(savedState); 
      _game = (TriviaGame)ViewState["Game"]; 
      _step = (int)ViewState["Step"]; 
     } 

     protected override object SaveViewState() 
     { 
      ViewState["Game"] = _game; 
      ViewState["Step"] = _step; 
      return base.SaveViewState();   
     } 


    } 

** 수정 ** 은 내가 이런 식으로하고 있어요 이유는 선언적으로 그들 각각의 전에로드를 갖는 다음 페이지로 모든 컨트롤을 추가 처리하는 것을 피하기 것을 추가해야 그들은로드해야합니다.

답변

1

Page_Init 또는 Page_PreInit 이벤트를 사용하십시오.

+0

이러한 이벤트는 사용할 수 없습니다. 그들은 viewstate가 deserialized되기 전에 발생합니다. 나는 내가 다루고있는 그 시점에서 어떤 통제인지 모른다. – Darthg8r

+0

또한 사용 된 자리 표시자가 아직 초기화되지 않았습니다. – Darthg8r

+0

InitComplete를 사용해 보았습니다. 내가 viewstate 및 자리 표시자를 가지고 있지만, 여전히 핸들을 얻을 수없는 동작이 있습니다. 버튼을 클릭하고, 2 단계, 1 단계, 1 단계, 3 단계, 1 단계, 4 단계를 차례로 클릭하십시오. – Darthg8r

1

이 설정은 매우 기괴합니다.

첫 번째 제안은 LoadStepControl() 중에 컨트롤에 ID를 명시 적으로 할당하여 컨트롤이 무엇이든 관계없이 동일한 ID를 갖도록하는 것입니다. 이것은 아마도 이벤트 핸들러의 손실에 도움이 될 것입니다. 나는 이벤트 핸들러에서 자리 표시자를 지우고 새 컨트롤을 추가 할 때 PreLoad()에서 첫 번째 사항을 추가 할 때와 다른 방식으로이 ID를 얻는다 고 추측합니다. 따라서 ID는 포스트 백간에 일치하지 않으므로 이벤트 처리기를 찾을 수 없습니다.

두 번째 제안은 접근 방식을 다시 적용하고 모든 컨트롤을 페이지에 정적으로 추가하고 가시성을 false로 설정하기 만하면됩니다. 측정 가능한 성능 문제가 실제로 발생하지 않는 한이 방법을 사용하면 많은 번거 로움을 피할 수 있습니다. 코드의 종류와 관련하여 많은 경험을 통해 말할 수 있습니다.)

제 3의 제안은 ASP.Net Wizard control을 사용해보세요.

+0

이벤트가 중단되는 것에 동의합니다. 동적으로 추가 된 컨트롤을 처리 할 때 가장 좋은 방법은 페이지에 다시 넣고 * Init() 이벤트 중 하나에서 이벤트를 다시 연결하여 컨트롤이 이벤트주기에 있도록하는 것입니다. 나는 또한 물건을 켜고 끄는 것은 총 재접속을하지 않는 한가는 길일 것입니다. 현재 접근 방식을 사용하면 페이지가 모든 컨트롤을 알고 있어야하므로 동적으로 스왑을 시도하는 이점은 없습니다. 컨트롤/단계를 데이터베이스에서 읽는다면 이것이 적절할 것입니다. –

+0

... 그냥 HTML과 CS 파일에 컨트롤을 가지고 있지만 그것들을 끄면 오버 헤드가 발생하지 않을 것입니다. –

1

Womp의 대답에 대한 귀하의 접근 방식에 대한 의견을 말했습니다. 그러나 사람들이 내 접근 방식을 무시하려고 할 때 나는 그것을 싫어한다. 왜냐하면 내가하려는 일의 전체적인 맥락을 보지 못하기 때문이다. 그렇다면 현재의 접근 방식에 대한 가능한 해결책을 제안 할 것입니다.

  1. 페이지 수명주기의 초기화 메소드에서 사용할 수 있도록 세션의 단계 또는 쿼리 문자열을 저장하십시오. viewstate로드를 기다리는 문제를 해결할 때까지 Womp가 가져온 이벤트 문제를 해결할 수 없습니다.
  2. 항상 페이지의 OnInit 또는 PreInit 이벤트 동안 각 다시 게시에서 step의 현재 값에 대한 자리 표시 자에 컨트롤을 추가하십시오. 또한이 시간에 이벤트를 다시 연결해야합니다. viewstate가로드되기 전에 모든로드에서이 작업을 수행해야합니다. 이것은 홀더의 컨트롤이 올바르게 초기화되었는지 확인하는 데 필수적입니다.
  3. 이벤트 처리기에서 지금 수행하는 것처럼 단계를 증가시키고 컨트롤 스왑을 트리거합니다 (이벤트 수명주기 전의 모든 시간에 컨트롤을 다시 설정하므로 항상 올바르게 실행됩니다).

예 : 페이지가 처음로드되면 AddEditGame.ascx 컨트롤을 소유자에두고 OnInit 중에 이벤트를 연결합니다. 사용자가 포스트를 다시 발생 시키면 AddEditGame.ascx 컨트롤을 홀더에 다시 놓고 이벤트를 일으킨 컨트롤 (AddEditGame.ascx)이 이벤트 사이클의 컨트롤 트리에 나타나도록 이벤트를 연결합니다. 이벤트가 처리되면 단계를 증가시키고 제어 스왑을 트리거하여 CrudQuestions.ascx를 홀더에 넣고 이벤트를 연결합니다.사용자가 포스트를 다시 발생 시키면 init 등에서 CrudQuestions.ascx를 place holder에 넣을 것입니다.

가장 큰 변화는 viewstate가로드되기를 기다릴 필요가 없다는 것입니다 어떤 단계를 거쳐야하는지 알기 위해 이벤트 사이클이 발생하기 전에 다시 게시를 일으킨 컨트롤을 페이지에 다시 넣어 이벤트가 올바르게 실행되도록합니다.

나는 이것이/도움이되기를 바랍니다.

관련 문제