2010-07-14 5 views
2

Treeview가있는 Masterpage가 있습니다. 거기에 몇몇 노드를 선택할 수 있습니다. Default.aspx의 자리 표시 자에 일부 항목을 가져와 선택하면 Panel에 이미지와 링크 버튼이 배치됩니다. 이처럼 :런타임에 이미지 및 링크 버튼이있는 패널 작성

alt text http://a.imageshack.us/img20/9206/foldersrb.jpg

이 코드는 Masterpage이있는 Default.aspx를에 있습니다.

 TreeView nav_tree = ((TreeView)Master.FindControl("treeview_Navigation")); 
     string selectedNode = nav_tree.SelectedNode.Value; 

     var query = from n in dc.Nemanet_Navigations 
        where n.UserId == userGuid && n.Nav_pID.ToString() == selectedNode && n.Nav_IsFile == false 
        orderby n.Nav_Name 
        select n; 
     foreach (var item in query) 
     { 

      Panel div = new Panel(); 
      div.ID = item.Nav_ID.ToString(); 
      div.CssClass = "BulletDiv"; 
      content_default.Controls.Add(div); 

      Image picture = new Image(); 
      picture.ImageUrl = "~/Icons/New_Folder.png"; 
      div.Controls.Add(picture); 

      div.Controls.Add(new LiteralControl("<br/>")); 

      LinkButton description = new LinkButton(); 
      description.Text = item.Nav_Name; 
      description.PostBackUrl = "default.aspx"; 
      div.Controls.Add(description); 

     } 

사이트가 포스트 백을 수행 할 때, 나는 위의 이미지에 결과를 얻을 트 리뷰에서 "Enska"를 클릭하면 말할 수, 난 런타임에 컨트롤러를 만들 때 문제가있는 것 같습니다. "펑크 팬더"를 클릭하면 오류가 발생합니다. ID와 제어 'ctl00 $ CPH_Main $ ctl05' 를 찾을 수 없었기 때문에

오류가 발생하거나 다른 제어 게시 후 동일한 ID 할당된다. ID가 이 아닌 경우이 오류를 방지하려면 포스트 백 이벤트를 발생시키는 컨트롤의 ID 속성을 명시 적으로 설정하십시오.

또한 런타임에 linkbutton에 대한 이벤트 처리기를 만들면 어떻게 모든 링크 버튼이 사용하는 하나의 이벤트 처리기를 만들 수 있습니까? 폴더와 링크 버튼을 클릭 할 수 있고 같은 위치에 링크하기를 원한다면 전체 패널을 클릭 할 수있게 만드는 것이 더 간단합니까? 그렇다면 어떻게하면 "OnClick"이벤트를 얻을 수 있습니까?

답변

1

귀하의 문제는 때로는 이해하기가 어려울 때와 관련이 있습니다 ASP.NET Page Lifecycle.

런타임에 작성한 컨트롤 계층 구조 은 다시 게시 요청 중에 페이지 수명주기의 정확한 시점에을 다시 생성하지 않습니다.

다른 웹 컨트롤 (예 : DataGrid)에서이 문제를 해결하기 위해 취하는 "고전적인"접근 방식은 포스트 백에서 컨트롤 계층을 포스트 백 값만으로 재구성 할 수 있도록 viewstate에로드 된 데이터를 직렬화하는 것입니다. 데이터베이스를 다시 질의한다). 그러나 이러한 접근 방식을 적용하는 것이 적절하지 않을 수도 있습니다.

대신 이전 제어 계층 구조를 작성하는 데 사용 된 item 키 값 (item.Nav_ID)의 배열 (또는 다른 일련 화 가능 열거 형)을 빌드하여 viewstate에 추가 할 수 있습니다.: 사전을 구축,

List<Int32> navIdValues = Page.ViewState("NavIdValues") as List<Int32>; 

쿼리를 다시 실행합니다

List<Int32> navIdValues = new List<Int32>(); 
foreach (var item in query) 
{ 
    navIdValues.Add(item.Nav_ID); 
} 
Page.ViewState("NavIdValues") = navIdValues 

그런 다음, 수신 게시의 Page.Init 이벤트 기간 동안, 값이 이전 요청의 컨트롤 계층 구조를 구축하는 데 사용 검색 항목의 접근 그들의 Nav_ID 작성자 :이 이전 요청에 존재했던 다음

IDictionary<Int32, ??itemtype??> items = query.ToDictionary(n => n.Nav_Id); 

그리고 컨트롤 계층 구조를 재 구축 :를

foreach (Int32 navId in navIdValues) 
{ 
    var item = items(navId); 

    Panel div = new Panel(); 
    div.ID = item.Nav_ID.ToString(); 
    div.CssClass = "BulletDiv"; 

    ... etc ... 
} 
컨트롤 계층 구조가 포스트 백 이벤트 처리 전에 다시 만들어 졌으므로 포스트 백 이벤트가 예상대로 실행됩니다. 이것은 가장 최적의 솔루션은 아니지만 실행 가능한 솔루션입니다.

관련 문제