2012-03-02 2 views
6

완벽하게 데이터 바인딩 할 수있는 CompositeDataBoundControl을 만들었습니다. 이제 같은 것을하고 싶지만 객체 목록이 아니라 단일 객체를 원합니다. 이유는 동료가 프런트 엔드 코드에 < % # Eval ("X") %>을 (를) 단순히 사용하는 것이 좋습니다.asp.net 단일 개체에 대한 CompositeDataBoundControl

문제는 CompositeDataBoundControl은 데이터 소스

CreateChildControls(System.Collections.IEnumerable dataSource, bool dataBinding) 

하나의 객체에 대해 같은 일을 할 수있는 방법이 있나요으로 컬렉션을 받아 내가 오버라이드 (override) 할 방법을 가지고 있다는 것입니다?

답변

4

당신은

<ctrl:SingleObjectView ID="productView" runat="server"> 
    <ItemTemplate> 
     <%# Eval("ProductName") %> 
     <br /> 
     <%# Eval("Price","{0:c}") %> 
    </ItemTemplate> 
</ctrl:SingleObjectView> 

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!Page.IsPostBack) 
     { 
     productView.DataSource = new { ProductName="My Product", Price="10"}; 
     productView.DataBind(); 
     } 
} 

그래서 데이터 소스는 IEnumerable를 구현하지 않는 개체를 수신 사용을 보여주기 위해 데이터 소스 특성을

public class SingleObjectView : CompositeDataBoundControl 
    { 
     private object dataSource; 
     public override object DataSource 
     { 
      get { return new List<object> { dataSource }; } 
      set { dataSource = value; } 
     } 


     protected override int CreateChildControls(System.Collections.IEnumerable dataSource, bool dataBinding) 
     { 
      SingleItem singleItem = null; 
      if (dataBinding) 
      { 
       var it = dataSource.GetEnumerator(); 
       it.MoveNext(); 

       singleItem = new SingleItem(it.Current); 
      } 
      else 
      { 
       singleItem = new SingleItem(null); 
      } 

      ItemTemplate.InstantiateIn(singleItem); 
      Controls.Add(singleItem); 
      if (dataBinding) 
       singleItem.DataBind(); 
      return 1; 
     } 


     [PersistenceMode(PersistenceMode.InnerProperty), TemplateContainer(typeof(SingleItem))] 
     public ITemplate ItemTemplate { get; set; } 
    } 

    public class SingleItem : Control, IDataItemContainer 
    { 
     public SingleItem(object dataItem) 
     { 
      DataItem = dataItem; 
     } 
     public object DataItem { get; set; } 

     public int DataItemIndex 
     { 
      get { return 0; } 
     } 

     public int DisplayIndex 
     { 
      get { return 0; } 
     } 
    } 

편집을 재정의해야하지만, 오버라이드 (override) SingleObjectView 컨트롤의 DataSource 속성은 CreateChildControls이 호출되도록합니다. 내가 단일 개체의 인스턴스를 허용하는 FormView를 사용

+0

이것은 정확히 TysHHTP가 시도하는 것입니다. – AngeloBad

+0

@AngeloBad, 내가 작성한이 컨트롤은 다음과 같이 사용됩니다. ctrlSingleObjectView.DataSource = singleObject; ctrlSingleObjectView.DataBind(); 나는 OP가 필요로하는 것이 정확히 그것이라고 믿습니다. –

+0

나는 왜이 대답이 downvoted인지 알고 싶습니다. –

2

컨트롤 목록을 만드는 방법에 대해 하나의 개체를 추가하고 메서드를 호출하는 방법은 무엇입니까?

+1

우리는 그 점을 알아 냈지만 괜찮은 해결책보다 해결 방법/해킹이 더 많다고 느낍니다. – Tys

+1

메서드에서 매개 변수로 IEnumerable을 수락하면 해시가 아닌 요소 1 개로 구성된 IEnumerable을 전달합니다. 내가 뭐라는지 알 겠어? – AngeloBad

+2

AngeloBad에 동의합니다. –

0

이 템플릿 수 :

protected void fvProduct_Init(object sender, EventArgs e) 
    { 
     // Load product template 
     fvProduct.ItemTemplate = LoadTemplate("Templates/ProductTemplate.ascx"); 

     // Bind product to data source 
     fvProduct.DataSource = new[] { Product }; 
     fvProduct.DataBind(); 
    } 

그런 ProductTemplate.ascx에서이 같은 물건을 수행 할 수 있습니다

이 시나리오에서
<h1><%# Eval("ProductName") %></h1> 
<p><%# Eval("Description") %></p> 
<h4><%# Eval("Price", "{0:C}")%></h4> 

당신은 당신이 있었다 언급 사용자 정의 컨트롤을 사용하지만 아이디어는 기본적으로 위의 답변과 같습니다. 하나의 항목으로 열거 형을 만들고 바인딩합니다. FormView을 사용하는 이유는 한 번에 하나의 항목 만 표시하도록 설계 되었기 때문입니다.

관련 문제