如何创建使用asp:ListItem列表作为子控件的ASP.NET用户/服务器控件?

9
我希望创建一个用户/服务器控件,该控件将使用类似以下代码的方式创建:
<my:MyListControl runat="server">
   <asp:ListItem Text="Test1" Value="Test1" />
   <asp:ListItem Text="Test2" Value="Test2" />
</my:MyListControl>

我这里只是想找一个起点:

文章或代码示例。

我应该从哪个基类继承?需要覆盖什么内容?

可能需要说明如何自定义控件接受的子项(使用 my:ListItem 而不是 asp:ListItem)。

我想要创建一个非常简单的面包屑导航控件,用于网站的一个小部分。我已经使用标准的 ASP.NET 控件实现了所有功能,但是添加子项需要在代码中进行,这意味着更正拼写错误或格式错误需要重新编译,这并不理想。

编辑:

以下是我的代码,并加入了 Josh 在下面的建议:

命名空间 MySite.Controls 部分类 BreadCrumbs 继承 UserControl

    Private m_BreadCrumbs As New List(Of BreadCrumbItem)

    <PersistenceMode(PersistenceMode.InnerProperty)> _
    Public Property Items() As List(Of BreadCrumbItem)
        Get
            Return m_BreadCrumbs
        End Get
        Set(ByVal value As List(Of BreadCrumbItem))
            m_BreadCrumbs = value
        End Set
    End Property

    Private Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
        Bind()
    End Sub

    Private Sub Bind()
        lvCrumbs.DataSource = Items
        Me.DataBind()
    End Sub
End Class

Public Class BreadCrumbItem
    Private m_Text As String
    Public Property Text() As String
        Get
            Return m_Text
        End Get
        Set(ByVal value As String)
            m_Text = value
        End Set
    End Property

    Private m_Url As String
    Public Property Url() As String
        Get
            Return m_Url
        End Get
        Set(ByVal value As String)
            m_Url = value
        End Set
    End Property
End Class

结束命名空间

然后我的页面代码看起来像这样:

<%@ Page Language="VB" AutoEventWireup="false" Inherits="MySite.MyPage" Title="My Page" Codebehind="MyPage.aspx.vb" %>
<%@ Register TagPrefix="my" Namespace="MySite.Controls" Assembly="MySite" %>
<my:BreadCrumbs ID="breadcrumbs" runat="server">
    <Items>
        <my:BreadCrumbItem Text="Another page" Url="AnotherPage.aspx" />
    </Items>
</my:BreadCrumbs>

最终的HTML标记目标是什么?类似于:<ul> <li>测试1</li> <li>测试2</li> </ul> 为什么需要使用ListItem而不是其他类型? - ahsteele
是的,我输出的HTML是ul/li格式的。不需要使用asp:ListItem,当我提问时不知道该怎么称呼它。 - slolife
2个回答

11

你可以在用户控件的代码后台添加一个属性,例如:

[PersistenceMode(PersistenceMode.InnerProperty)]
public List<ListItem> Items
{
    get;
    set;
}
您的标记将如下所示:
<my:MyListControl runat="server">
  <Items>
    <asp:ListItem/>
  </Items>
</my:myListControl>
为了使 ListItem 变成自己的列表项(我建议这样做,而不是使用 asp.net),您需要创建自己的类。
以下是我使用的服务器控件示例(我删除了很多噪音,因此这只是一个框架):
   [ToolboxData("<{0}:Menubar runat=server></{0}:Menubar>")]
    [System.ComponentModel.DesignTimeVisible(false)]
    public class Menubar : WebControl, IPostBackEventHandler
    {

        private List<MenuItem> _menuItems = new List<MenuItem>();
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public List<MenuItem> MenuItems
        {
            get
            {
                return _menuItems;
            }
        }

    }
    [ToolboxItem(false)]
    [ParseChildren(true, "MenuItems")]
    public class MenuItem
    {
        private string _clientClick;
        private List<MenuItem> _menuItems = new List<MenuItem>();

        [Localizable(true)]
        public string Title { get; set; }
        public string Href { get; set; }
        public string Id { get; set; }
        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public List<MenuItem> MenuItems
        {
            get { return _menuItems; }
            set { _menuItems = value; }
        }
    }
现在我可以像这样使用它:
<my:Menubar runat="server" ID="menuBar">
    <MenuItems>
        <my:MenuItem Title="Save" Href="javascript:saveItem(this);"  />
        <my:MenuItem Title="Print" Href="javascript:void(0);">
            <MenuItems>
                <my:MenuItem Title="Preview" Href=""/>
                <my:MenuItem Title="To Pdf" Href="javascript:"/>
            </MenuItems>
        </my:MenuItem>
    </MenuItems>
</my:Menubar>

这似乎是我需要的。我现在唯一的问题是为什么我的@Register TagPrefix="my" Namespace="MySite.Controls"不能用来获取自定义列表项类?有什么想法吗?它可以获取父控件(例如您的Menubar),但我无法在Items标记内使用my:MyListItem。 - slolife
没关系。需要在@Register指令中添加Assembly参数。现在它可以工作了。谢谢Josh。 - slolife

0
使用asp:Repeater,然后将其绑定到您想要在面包屑中显示的对象列表。您可以使用模板自定义项目本身和分隔符。

我想要的比repeater控件更加明确一些。 - slolife

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接