Question

J'écris un contrôle Composite, qui contient une liste pour afficher un tableau d'éléments. Normalement, lors de l’utilisation d’un ListView dans Asp.NET, je définirais les modèles dans le code-forward.

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

Je suppose que c'est quelque chose comme:

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

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

Mise à jour: J'ai créé 2 modèles en implémentant l'interface ITemplate:

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

et je peux les ajouter en utilisant:

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

Mais je reste bloqué car container.DataItem est null.

Était-ce utile?

La solution

L'astuce consiste à s'abonner à l'événement de liaison de données du titulaire itemplaceholder dans ItemTemplate.

La solution complète:

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

Autres conseils

Ce lien pourrait-il vous être utile?

La génération des modèles au moment de la conception (afin de les conserver dans le fichier aspx) est un peu plus délicate, mais la liaison de données fonctionnera automatiquement.

L'exemple suivant: Sonteks, voici un exemple qui crée un modèle contenant des éléments qui sont ensuite liés à l'aide de la liaison de données.

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

}

Configurez une classe telle que:

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

Et procédez comme suit:

 view.LayoutTemplate = new GenericTemplateImplementation(p =>
                {
                    p.Controls.Add(new Label { Text = "Foo" });
                });
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top