2012-03-02 14 views
6

He creado un CompositeDataBoundControl que puedo databind perfectamente bien. Ahora quiero hacer lo mismo, pero no para una lista de objetos, sino para un solo objeto. Las razones es que quiero que mis colegas tengan la capacidad de simplemente usar el <% # Eval ("X")%> en su código front-end.asp.net CompositeDataBoundControl para un solo objeto

El problema es que el CompositeDataBoundControl tiene un método que tengo que anular, que sólo acepta una colección como una fuente de datos

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

¿Hay una manera de hacer lo mismo para un solo objeto?

Respuesta

4

Necesita anular la propiedad DataSource

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; } 
     } 
    } 

de edición para mostrar el uso

<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(); 
     } 
} 

lo tanto, el origen de datos recibe un objeto que no implementa IEnumerable, pero reemplazando el La propiedad DataSource del control SingleObjectView asegura que se llame al CreateChildControls.

+0

Esto es exactamente lo que TysHHTP intenta hacer. – AngeloBad

+0

@AngeloBad, este control que escribí se usa así: ctrlSingleObjectView.DataSource = singleObject; ctrlSingleObjectView.DataBind(); Creo que es exactamente lo que OP necesita. –

+0

Me gustaría saber por qué esta respuesta fue downvoted .. –

2

¿Qué tal crear una lista de control, agregar un solo objeto y luego llamar al método?

+1

Nos dimos cuenta de eso también, pero se siente más como una solución/truco que como una solución decente. – Tys

+1

Si un método acepta un parámetro IEnumerable, pasar un IEnumerable compuesto por solo 1 elemento no es un hack. ¿Sabes lo que quiero decir? – AngeloBad

+2

Estoy de acuerdo con AngeloBad. –

0

utilizo FormView para permitir una instancia de un solo objeto a plantilla:

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(); 
    } 

Luego, en ProductTemplate.ascx que puede hacer cosas como esta:

<h1><%# Eval("ProductName") %></h1> 
<p><%# Eval("Description") %></p> 
<h4><%# Eval("Price", "{0:C}")%></h4> 

En su escenario se ha mencionado que se utilizando un control personalizado, pero la idea es básicamente la misma que las respuestas anteriores. Simplemente crea un enumerable con un elemento y lo vincula. La razón para usar un FormView es porque está diseñado para mostrar solo un elemento a la vez.

Cuestiones relacionadas