10

我正在编写一个复合控件,其中包含一个列表视图来显示项目表。通常在 Asp.NET 中使用 ListView 时,我会在代码转发中定义模板。

<asp:ListView runat="server" ID="ArticleList">
    <LayoutTemplate>
        <div class="ContentContainer">
            <div runat="server" id="itemPlaceholder" />
        </div>
    </LayoutTemplate>
    <ItemTemplate>
        <div>
            <div><%# Eval("Content") %></div>
        </div>
    </ItemTemplate>
    </asp:ListView>

我假设它是这样的:

ListView view = new ListView();
view.LayoutTemplate = .....
view.ItemTemplate = .....

// when do I call these?
view.DataSource = myDataSource;
view.DataBind();

更新: 我通过实现 ITemplate 接口创建了 2 个模板:

private class LayoutTemplate : ITemplate
{
    public void InstantiateIn(Control container)
    {
        var outer = new HtmlGenericControl("div");
        var inner = new HtmlGenericControl("div") { ID = "itemPlaceholder" };
        table.Rows.Add(row);

        container.Controls.Add(table);
    }
}

private class ItemTemplate : ITemplate
{
    public void InstantiateIn(Control container)
    {
        var inner = new HtmlGenericControl("div");

        container.Controls.Add(inner);
    }
}

我可以使用以下方法添加它们:

dataList.LayoutTemplate = new LayoutTemplate();
dataList.ItemTemplate = new ItemTemplate();

但后来我卡住了,因为 container.DataItem 为空。

4

4 回答 4

9

诀窍是在 ItemTemplate 中订阅 itemplaceholder 的数据绑定事件。

完整的解决方案:

public class FibonacciControl : CompositeControl
{
    public FibonacciControl()
    {
        // ....
    }

    protected override void CreateChildControls()
    {
        base.CreateChildControls();

        ListView view = new ListView();

        view.LayoutTemplate = new LayoutTemplate();
        view.ItemTemplate = new ItemTemplate();

        view.DataSource = FibonacciSequence();
        view.DataBind();

        this.Controls.Add(view);
    }

    private IEnumerable<int> FibonacciSequence()
    {

        int i1 = 0;
        int i2 = 1;

        for (int i = 0; i < Iterations; i++)
        {
            yield return i1 + i2;
            int temp = i1 + i2;
            i1 = i2;
            i2 = temp;
        }
        yield break;
    }

    public int Iterations { get; set; }

    private class LayoutTemplate : ITemplate
    {

        public void InstantiateIn(Control container)
        {
            var ol = new HtmlGenericControl("ol");
            var li = new HtmlGenericControl("li") { ID = "itemPlaceholder" };
            ol.Controls.Add(li);

            container.Controls.Add(ol);
        }
    }

    private class ItemTemplate : ITemplate
    {
        public void InstantiateIn(Control container)
        {
            var li = new HtmlGenericControl("li");

            li.DataBinding += DataBinding;
            container.Controls.Add(li);
        }

        public void DataBinding(object sender, EventArgs e)
        {
            var container = (HtmlGenericControl)sender;
            var dataItem = ((ListViewDataItem)container.NamingContainer).DataItem;

            container.Controls.Add( new Literal(){Text = dataItem.ToString() });
        }
    }
}
于 2008-09-29T14:50:12.467 回答
3

这个链接能有帮助吗?以编程方式使用模板化控件

在设计时生成模板(以便将它们保存在 aspx 文件中)有点棘手,但 DataBinding 将自动工作。

于 2008-09-18T15:00:07.983 回答
0

此处以 Sonteks 示例为基础是一个创建模板的示例,该模板包含然后使用数据绑定绑定的元素。

public partial class View : PortalModuleBase
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    #region MasterListView_ItemDataBound
    public void MasterListView_ItemDataBound(object sender, ListViewItemEventArgs e)
    {
        ListViewItem objListViewItem = (ListViewItem)e.Item;
        ListViewDataItem objListViewDataItem = objListViewItem as ListViewDataItem;

        if (objListViewDataItem != null)
        {
            Tab objTab = (Tab)objListViewDataItem.DataItem;
            IEnumerable<Tab> Tabs = CustomData(objTab.TabID);

            Label TabIDLabel = (Label)objListViewItem.FindControl("TabIDLabel");
            Label TabNameLabel = (Label)objListViewItem.FindControl("TabNameLabel");

            TabIDLabel.Text = objTab.TabID.ToString();
            TabNameLabel.Text = objTab.TabName;

            AddListView(objTab.TabName, objListViewItem, Tabs);
        }
    }
    #endregion

    #region CustomData
    static IEnumerable<Tab> CustomData(int? ParentID)
    {
        TabAdminDataContext objTabAdminDataContext = new TabAdminDataContext();

        var myCustomData = from Tabs in objTabAdminDataContext.Tabs
                           where Tabs.ParentId == ParentID
                           select Tabs;

        return myCustomData.AsEnumerable();
    }
    #endregion

    #region AddListView
    private void AddListView(string CurrentTabName, Control container, IEnumerable<Tab> ChildTabs)
    {
        // The Tab has Children so add a ListView
        if (ChildTabs.Count() > 0)
        {
            ListView ChildListView = new ListView();
            ChildListView.ID = "ChildListView";
            ChildListView.ItemCommand += ListView_ItemCommand;
            ChildListView.EnableViewState = true;
            ChildListView.LayoutTemplate = new MyLayoutTemplate();
            ChildListView.ItemTemplate = new MyItemTemplate();
            ChildListView.DataSource = ChildTabs;
            ChildListView.DataBind();

            // Put the ListView in a Panel
            var oTR = new HtmlGenericControl("tr") { ID = "ChildListViewTR" };
            var oTD = new HtmlGenericControl("td") { ID = "ChildListViewTD" };

            Panel objPanel = new Panel();
            objPanel.ID = "ListViewPanel";
            objPanel.ToolTip = CurrentTabName;
            objPanel.Controls.Add(ChildListView);

            oTD.Controls.Add(objPanel);
            oTR.Controls.Add(oTD);
            container.Controls.Add(oTR);
        }
    }
    #endregion

    #region ListView_ItemCommand
    protected void ListView_ItemCommand(object sender, ListViewCommandEventArgs e)
    {
        LinkButton objButton = (LinkButton)sender;
        Label1.Text = objButton.Text;
        MasterListView.DataBind();
    }
    #endregion

    #region MyLayoutTemplate
    public class MyLayoutTemplate : ITemplate
    {
        public void InstantiateIn(Control container)
        {
            var oTR = new HtmlGenericControl("tr") { ID = "itemPlaceholder" };
            container.Controls.Add(oTR);
        }
    }
    #endregion

    #region ItemTemplate
    public class MyItemTemplate : ITemplate
    {
        public void InstantiateIn(Control container)
        {
            var oTR = new HtmlGenericControl("tr");

            var oTD1 = new HtmlGenericControl("td");
            LinkButton TabIDLinkButton = new LinkButton();
            TabIDLinkButton.ID = "TabIDLinkButton";
            oTD1.Controls.Add(TabIDLinkButton);
            oTR.Controls.Add(oTD1);

            var oTD2 = new HtmlGenericControl("td");
            Label TabNameLabel = new Label();
            TabNameLabel.ID = "TabNameLabel";
            oTD2.Controls.Add(TabNameLabel);
            oTR.Controls.Add(oTD2);

            oTR.DataBinding += DataBinding;
            container.Controls.Add(oTR);
        }

        public void DataBinding(object sender, EventArgs e)
        {
            var container = (HtmlGenericControl)sender;
            var dataItem = ((ListViewDataItem)container.NamingContainer).DataItem;
            Tab objTab = (Tab)dataItem;

            LinkButton TabIDLinkButton = (LinkButton)container.FindControl("TabIDLinkButton");
            Label TabNameLabel = (Label)container.FindControl("TabNameLabel");

            TabIDLinkButton.Text = "+" + objTab.TabID.ToString();
            TabNameLabel.Text = objTab.TabName;

            IEnumerable<Tab> ChildTabs = View.CustomData(objTab.TabID);

            View objView = new View();
            objView.AddListView(objTab.TabName, container, ChildTabs);
        }

    }
    #endregion

}
于 2008-12-07T21:50:18.670 回答
-1

设置一个类,如:

public delegate void InstantiateTemplateDelegate(Control container);

public class GenericTemplateImplementation : ITemplate
{
    private InstantiateTemplateDelegate instantiateTemplate;

    public void InstantiateIn(Control container)
    {
        this.instantiateTemplate(container);
    }

    public GenericTemplateImplementation(InstantiateTemplateDelegate instantiateTemplate)
    {
        this.instantiateTemplate = instantiateTemplate;
    }
}

然后执行以下操作:

 view.LayoutTemplate = new GenericTemplateImplementation(p =>
                {
                    p.Controls.Add(new Label { Text = "Foo" });
                });
于 2008-09-18T17:09:21.590 回答