2014-07-21 58 views
2

如何根據項目的類型選擇模板,並使用多個模板進行中繼器控制?帶多個模板的ASP中繼器控制

這是我目前:

我的中繼器類:

[ToolboxData("<{0}:LifestreamRepeater runat=server>")] 
public class LifestreamRepeater : Repeater 
{ 

    [PersistenceMode(PersistenceMode.InnerProperty)] 
    public ITemplate TwitterTemplate {get; set;} 


    protected override void OnDataBinding(EventArgs e) 
    { 
     //base.OnDataBinding(e); 
     foreach (var item in (IEnumerable<LifestreamItem>)this.DataSource) 
     { 
      if (item is LifestreamTwitterItem) 
      { 
       LifestreamRepeaterItem ri = new LifestreamRepeaterItem(item); 
       TwitterTemplate.InstantiateIn(item); 
      } 
      else 
      { 
       ItemTemplate.InstantiateIn(item); 
      } 
     } 

    } 
} 

和前端:

 <lfs:LifestreamRepeater runat="server" ID="repeater1"> 
      <TwitterTemplate> 
       <div class="Lifestream Twitter Item"> 
        <h4> <%# DataBinder.Eval(Container.DataItem, "Title")%> </h4> 
        <p> <%# DataBinder.Eval(Container.DataItem, "Body")%> </p> 
       </div> 
      </TwitterTemplate> 
      <ItemTemplate> 
       <div class="Lifestream Item"> 
        <h2> <%# DataBinder.Eval(Container.DataItem, "Title")%> </h2> 
        <p> <%# DataBinder.Eval(Container.DataItem, "Body")%> </p> 
       </div> 
      </ItemTemplate> 
     </lfs:LifestreamRepeater> 

然後我Repeater控件綁定到LifestreamItem的IEnumerable其中是多種不同社交網絡帖子類型的基類,因此可能存在TwitterLifestreamItem和VimeoLifestreamItem,我希望轉發器選擇不同的臨時文件後期,具有不同的可能值,取決於數據項。

回答

0

看來,解決辦法是重寫DataBind方法是這樣的:

public override void DataBind() 
    { 
     foreach (var item in (IEnumerable<LifestreamItem>)this.DataSource) 
     { 
      if (item is LifestreamTwitterItem) 
      { 
       TwitterTemplate.InstantiateIn(item); // instantiate inside the item which is also a control. 
      } 
      else 
      { 
       ItemTemplate.InstantiateIn(item); 
      } 
      item.DataBind(); // bind the item 
      Controls.Add(item); // add the item to the repeater 
     } 
    } 
1

我不認爲有什麼建設成爲ASP.NET,允許這一點,但你可以這樣做:

<asp:Repeater ID="myRepeater" runat="server" OnItemDataBound="myRepeater_ItemDataBound"> 
    <ItemTemplate> 
     <asp:PlaceHolder ID="twitterTemplate" Visible="false" runat="server"> 
      <asp:Literal ID="fooTwitterControl" runat="server" /> 
     </asp:PlaceHolder> 

     <asp:PlaceHolder ID="itemTemplate" Visible="false" runat="server"> 
      <asp:Literal ID="fooItemControl" runat="server" /> 
     </asp:PlaceHolder> 
    </ItemTemplate> 
</asp:Repeater> 

而且ItemDataBound事件:

protected void myRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e) 
{ 
    if (ListItemType.Item == e.Item.ItemType || ListItemType.AlternatingItem == e.Item.ItemType) 
    { 
     PlaceHolder twitterTemplate = (PlaceHolder)e.Item.FindControl("twitterTemplate"); 
     PlaceHolder itemTemplate = (PlaceHolder)e.Item.FindControl("itemTemplate"); 

     var item = (LifestreamItem)e.Item.DataItem; 
     if (item is LifestreamTwitterItem) 
     { 
      twitterTemplate.Visible = true; 

      Literal fooTwitterControl = (Literal)e.Item.FindControl("fooTwitterControl"); 
      // Load all twitter related controls + populate 
     } 
     else 
     { 
      itemTemplate.Visible = true; 
      Literal fooItemControl = (Literal)e.Item.FindControl("fooItemControl"); 
      // Load all non-twitter controls + populate 
     } 
    } 
} 

從本質上講,ItemTemplates成爲佔位符並根據您正在迭代的類型啓用/禁用。

+0

雖然這會的工作,我真的找東西,可以是由設計師輕鬆直接地使用。我可以自定義控件嗎? – Steve

+0

@Steve Yep,自定義控件相對容易創建。只需從'repeater'類繼承 – DGibbs