【问题标题】:ASP.NET: Build user control that take a list as parameter?ASP.NET:构建以列表为参数的用户控件?
【发布时间】:2010-01-13 08:28:33
【问题描述】:

如何构建一个以列表为参数的用户控件,即:

<foo:TabMenu runat="server">
<Tabs>
<Tab Label="Tab1" PanelId="pnlTab1"/>
<Tab Label="Tab2" PanelId="pnlTab2"/>
<Tab Label="Tab3" PanelId="pnlTab3"/>
</Tabs>
</foo:TabMenu>

【问题讨论】:

  • 这是您想要的输出示例吗?还是输入?
  • 这就是我希望在完成后使用控件的方式。我不知道如何构建一个将自定义类/结构列表作为属性的用户控件?

标签: c# asp.net


【解决方案1】:

你需要这样的东西。一切正常,但你必须完成 TabCollection 类。

编辑:对不起,我没有测试代码。反正发现了一些问题就解决了。

用户控制

[ParseChildren(true, "Tabs"), PersistChildren(false)]
public partial class TabMenu : UserControl
{

    private TabCollection _tabs;

    [Browsable(false), PersistenceMode(PersistenceMode.InnerProperty), MergableProperty(false)]
    public virtual TabCollection Tabs
    {
        get
        {
            if (this._tabs == null)
                this._tabs = new TabCollection(this);
            return this._tabs;
        }
    }

    protected override ControlCollection CreateControlCollection()
    {
        return new TabMenuControlCollection(this);
    }

}

标签

public class Tab : HtmlGenericControl
{

    public string Label
    {
        get { return (string)ViewState["Label"] ?? string.Empty; }
        set { ViewState["Label"] = value; }
    }

}

TabCollection

public class TabCollection : IList, ICollection, IEnumerable
{

    private TabMenu _tabMenu;

    public TabCollection(TabMenu tabMenu)
    {
        if (tabMenu == null)
            throw new ArgumentNullException("tabMenu");

        this._tabMenu = tabMenu;
    }

    public virtual int Add(Tab tab)
    {
        if (tab == null)
            throw new ArgumentNullException("tab");

        this._tabMenu.Controls.Add(tab);

        return this._tabMenu.Controls.Count - 1;
    }

    int IList.Add(object value)
    {
        return this.Add((Tab)value);
    }

    // You have to write other methods and properties as Add.

}

TabMenuControlCollection

public class TabMenuControlCollection : ControlCollection
{

    public TabMenuControlCollection(TabMenu owner) : base(owner) { }

    public override void Add(Control child)
    {
        if (child == null)
            throw new ArgumentNullException("child");

        if (!(child is TabMenu))
            throw new ArgumentException("The TabMenu control can only have a child of type 'Tab'.");

        base.Add(child);
    }

    public override void AddAt(int index, Control child)
    {
        if (child == null)
            throw new ArgumentNullException("child");

        if (!(child is TabMenu))
            throw new ArgumentException("The TabMenu control can only have a child of type 'Tab'.");

        base.AddAt(index, child);
    }

}

【讨论】:

  • 不错!我得到了:Foo.Presentation.Controls.TabCollection 必须有“Foo.Presentation.Controls.Tab”类型的项目。 “选项卡”的类型为“System.Web.UI.HtmlControls.HtmlGenericControl”。
  • 知道为什么 Visual Studio 只知道“TabMenu”和“Tabs”,而不知道在编辑 aspx 页面(用于自动完成)期间的“Tab”控件吗?
  • @dcg 你的代码和上面的完全一样,还是有什么不同?
  • 应该是一样的。它工作正常。但是,当我尝试编辑 aspx 文件时,Visual Studio 不会“看到”内部子项和属性。此外,它突出显示了 aspx 代码,说它是一个无效的模式...... :-/ 这是我丢失“轨道”的地方。有什么想法吗?
【解决方案2】:

这是一个非常简单的解决方案。

Partial Class UserControlStrings_TabMenu
    Inherits System.Web.UI.UserControl

    Private _Tabs As New MyTabsClass(Me)

    <PersistenceMode(PersistenceMode.InnerProperty)>
    Public ReadOnly Property Tabs As MyTabsClass
        Get
            Return _Tabs
        End Get
    End Property
End Class

Public Class MyTabsClass
    Inherits ControlCollection

    Sub New(ByVal owner As Control)
        MyBase.New(owner)
    End Sub

    Public Overrides Sub Add(ByVal child As System.Web.UI.Control)
        MyBase.Add(New MyTab(child))
    End Sub
End Class


Public Class MyTab
    Inherits HtmlGenericControl

    Sub New(ByVal GenericControl As HtmlGenericControl)
        MyBase.New()
        Me.Label = GenericControl.Attributes("Label")
        Me.PanelId = GenericControl.Attributes("Panelid")
    End Sub

    Public Property Label As String = String.Empty
    Public Property PanelId As String = String.Empty

    Public Overrides Function ToString() As String
        Return Me.Label & "-" & Me.PanelId
    End Function
End Class

(C#版本)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
partial class UserControlStrings_MyControl : System.Web.UI.UserControl
{


    private MyTabsClass _Tabs = new MyTabsClass(this);

    [System.Web.UI.PersistenceMode(System.Web.UI.PersistenceMode.InnerProperty)]
    public MyTabsClass Tabs {
        get { return _Tabs; }
    }
}

public class MyTabsClass : System.Web.UI.ControlCollection
{

    public MyTabsClass(System.Web.UI.Control owner) : base(owner)
    {
    }

    public override void Add(System.Web.UI.Control child)
    {
        base.Add(new MyTab(child));
    }
}


public class MyTab : System.Web.UI.HtmlControls.HtmlGenericControl
{

    public MyTab(System.Web.UI.HtmlControls.HtmlGenericControl GenericControl) : base()
    {
        this.Label = GenericControl.Attributes("Label");
        this.PanelId = GenericControl.Attributes("Panelid");
    }


    private string _Label = System.String.Empty;
    public string Label {
        get { return _Label; }
        set { _Label = value; }
    }

    private string _PanelId = System.String.Empty;
    public string PanelId {
        get { return _PanelId; }
        set { _PanelId = value; }
    }

    public override string ToString()
    {
        return this.Label + "-" + this.PanelId;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-22
    • 2023-04-08
    • 2011-02-12
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-17
    相关资源
    最近更新 更多