【问题标题】:ASP Repeater control with multiple templates具有多个模板的 ASP 中继器控件
【发布时间】:2014-07-21 15:47:28
【问题描述】:

我怎样才能有一个带有多个模板的转发器控件,其中选择的模板是基于项目的类型?

这是我目前拥有的:

我的复读班:

[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>

然后我将转发器控件绑定到 LifestreamItem 的 IEnumerable,它是多个不同社交网络帖子类型的基类,因此可能存在 TwitterLifestreamItem 和 VimeoLifestreamItem,我希望转发器选择具有不同可能值的不同模板,具体取决于在数据项上。

【问题讨论】:

标签: c# asp.net razor


【解决方案1】:

似乎解决方案是像这样覆盖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
        }
    }

【讨论】:

    【解决方案2】:

    我认为 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 成为占位符并根据您正在迭代的类型启用/禁用。

    【讨论】:

    • 虽然可行,但我真的在寻找设计师可以轻松直接使用的东西。我可以制作一个自定义控件来执行此操作吗?
    • @Steve 是的,自定义控件相对容易创建。只需从repeater 类继承
    猜你喜欢
    • 1970-01-01
    • 2017-01-12
    • 2010-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多