2008-11-08 3 views
4

XML 구성에 의한 사용자 정의 컨트롤을 설정 중입니다. 예를 들어 설명하는 것이 더 쉽습니다. 다음 구성 가져온 부분을 살펴 보자 내가 하나의 텍스트 박스와 체크 박스 컨트롤에 그 조각을 번역 달성하기 위해 노력하고있어데이터 바인딩 된 리피터 내에 조건부 콘텐츠를 만드는 방법

<node> 
    <text lbl="Text:"/> 
    <checkbox lbl="Check me:" checked="true"/> 
</node> 

. 물론 스 니펫에 더 많은 노드가 포함되어 있으면 더 많은 컨트롤이 자동으로 생성됩니다.

작업의 반복적 인 특성을 알려주십시오. 리피터를 사용하기로했습니다. 그 안에는 두 개의 컨트롤 (하나 이상, 아래 참조) 컨트롤, 하나의 CheckBox 및 하나의 Editbox가 있습니다. 활성화 할 컨트롤을 선택하기 위해 인라인 스위치 명령을 사용하여 현재 구성 노드의 이름을 확인했습니다.

슬프게도, 작동하지 않습니다. 문제는 데이터 바인딩이 발생한 후 오랫동안 렌더링 시간 동안 스위치가 실행되고 있다는 사실에 있습니다. 그 자체만으로는 문제가되지 않을 것입니다. 구성 노드가 데이터 바인딩에 필요한 정보를 제공 할 수 있다는 사실 때문 만은 아닙니다. 체크 상자 컨트롤이 위의 스 니펫에있는 텍스트 노드에 바인딩하려고 시도 할 때 필자가 "checked"속성을 찾고자한다면 무슨 일이 일어날 지 생각해보십시오.

아이디어를 만드는 방법은 무엇입니까?

감사합니다, 보아스 여기

내 현재 코드입니다 :

여기

은 (위의 것보다 더 복잡한 구문에서 실행) 내 코드입니다 :

<asp:Repeater ID="settingRepeater" runat="server"> 
     <ItemTemplate> 
      <% 
       switch (((XmlNode)Page.GetDataItem()).LocalName) 
       { 
       case "text": 
      %> 
      <asp:Label ID="settingsLabel" CssClass="editlabel" Text='<%# XPath("@lbl") %>' runat="server" /> 
      <asp:TextBox ID="settingsLabelText" Text='<%# SettingsNode.SelectSingleNode(XPath("@xpath").ToString()).InnerText %>' 
       runat="server" AutoPostBack="true" Columns='<%# XmlUtils.OptReadInt((XmlNode)Page.GetDataItem(),"@width",20) %>' 
       /> 
      <% break; 
       case "checkbox": 
      %> 
      <asp:CheckBox ID="settingsCheckBox" Text='<%# XPath("@lbl") %>' runat="server" 
         Checked='<%# ((XmlElement)SettingsNode.SelectSingleNode(XPath("@xpath").ToString())).HasAttribute(XPath("@att").ToString()) %>' 
      /> 
      <% break; 
       } %> 
      &nbsp;&nbsp; 
     </ItemTemplate> 
    </asp:Repeater> 

답변

4

주말에 한 가지 해결책은 다음과 같습니다. 필자의 주요 목표는 마크 업에서 항목 템플리트의 정확한 내용을 지정하는 작업을 수행 할 수있는 무언가를 찾는 것이 었습니다. 코드에서 일을하면 효과가 있지만 여전히 성 가실 수 있습니다.

코드는 다음과 같이 곧장 앞으로 나올 수 있지만 문제의 요지는 두 부분으로되어 있습니다.

첫 번째는 Repeater item created 이벤트를 사용하여 원하지 않는 템플릿 부분을 필터링하는 것입니다.

두 번째는 게시하는 동안 페이지를 다시 만들 때 ViewState에서 작성한 결정을 저장하는 것입니다. 나중에 Item.DataItem을 사용했음을 알게 될 것입니다. 포스트 백 동안 제어 레크레이션은 페이지 수명주기의 훨씬 이전에 발생합니다. ItemCreate가 발생하면 DataItem은 null입니다.

제어 마크 업

<asp:Repeater ID="settingRepeater" runat="server" 
      onitemcreated="settingRepeater_ItemCreated" 
      > 
     <ItemTemplate> 
      <asp:PlaceHolder ID="text" runat="server"> 
        <asp:Label ID="settingsLabel" CssClass="editlabel" Text='<%# XPath("@lbl") %>' runat="server" /> 
        <asp:TextBox ID="settingsLabelText" runat="server" 
         Text='<%# SettingsNode.SelectSingleNode(XPath("@xpath").ToString()).InnerText %>' 
        Columns='<%# XmlUtils.OptReadInt((XmlNode)Page.GetDataItem(),"@width",20) %>' 

        /> 

      </asp:PlaceHolder> 
      <asp:PlaceHolder ID="att_adder" runat="server"> 
       <asp:CheckBox ID="settingsAttAdder" Text='<%# XPath("@lbl") %>' runat="server" 
          Checked='<%# ((XmlElement)SettingsNode.SelectSingleNode(XPath("@xpath").ToString())).HasAttribute(XPath("@att").ToString()) %>' 
       /> 
      </asp:PlaceHolder> 
     </ItemTemplate> 
    </asp:Repeater> 

주 : 추가 편의를 위해 내가 그룹 것들에 대한 자리 표시 자 컨트롤을 추가하고 쉽게 제거 제어하는의 결정을

여기 내 솔루션입니다.

코드

뒤에 코드를 넣고 모든 리피터 항목이 유형이라는 개념에 내장되어 있습니다. 유형은 구성 xml에서 추출됩니다. 내 특정 시나리오에서는 ID를 통해 단일 컨트롤로 해당 유형을 만들 수 있습니다. 필요한 경우 쉽게 수정할 수 있습니다.

protected List<string> repeaterItemTypes 
    { 
     get 
     { 
     List<string> ret = (List<string>)ViewState["repeaterItemTypes"]; 
     if (ret == null) 
     { 
      ret = new List<string>(); 
      ViewState["repeaterItemTypes"] = ret; 
     } 
     return ret; 
     } 
    } 

    protected void settingRepeater_ItemCreated(object sender, RepeaterItemEventArgs e) 
    { 
     string type; 
     if (e.Item.DataItem != null) 
     { 
     // data binding mode.. 
     type = ((XmlNode)e.Item.DataItem).LocalName; 
     int i = e.Item.ItemIndex; 
     if (i == repeaterItemTypes.Count) 
      repeaterItemTypes.Add(type); 
     else 
      repeaterItemTypes.Insert(e.Item.ItemIndex, type); 
     } 
     else 
     { 
     // restoring from ViewState 
     type = repeaterItemTypes[e.Item.ItemIndex]; 
     } 

     for (int i = e.Item.Controls.Count - 1; i >= 0; i--) 
     { 
     if (e.Item.Controls[i].ID != type) e.Item.Controls.RemoveAt(i); 
     } 
    } 
1

당신은 뭔가가 필요 그 모양은 다음과 같습니다.

<ItemTemplate> 
    <%# GetContent(Page.GetDataItem()) %> 
</ItemTemplate> 

그리고 나서 컨트롤은 코드 숨김으로 생성됩니다.