【问题标题】:Collection Type Property Assignable at Design Time in User Control用户控件中设计时可分配的集合类型属性
【发布时间】:2012-03-08 19:14:34
【问题描述】:

我正在创建一个用户控件,其中有一个名为 Items 的属性。 Items 的类型为 LibraryPanelBarItemCollection(自定义类),其中包含 LibraryPanelBarItem 对象的集合。我希望能够在设计时使用 VS 用于添加诸如树节点/列表视图项之类的东西的集合编辑器来添加这些。理想情况下,我还可以以声明方式将它们添加到 html 语法中。我可以让 Items 属性显示出来,但我没有智能感知来在开始标签和结束标签之间添加项目。

在我的用户控件中,我使用属性声明了以下属性

 <ParseChildren(True, "Items")> _
 Public Class LibraryPanelBar
Inherits System.Web.UI.UserControl

<PersistenceMode(PersistenceMode.InnerDefaultProperty)> _
<Browsable(True)> _
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
Public Property Items As LibraryPanelBarItemCollection

...Do Some Stuff...

End Class

这是我的 LibraryPanelBarItem 和 LibraryPanelBarItemCollection 的自定义类

Public Class LibraryPanelBarItem
<BindableAttribute(True)> _
Public Property ImageUrl As String

<BindableAttribute(True)> _
Public Property NavigateUrl As String
Public Property Text As String
Public Property Disabled As Boolean
Public Property ID As String
<PersistenceMode(PersistenceMode.InnerDefaultProperty)> _
Public Property Items As LibraryPanelBarItemCollection
Public ReadOnly Property HasChildren() As Boolean
    Get
        If Items.Count > 0 Then
            Return True
        Else
            Return False
        End If
    End Get
End Property


Public Sub New()
    Items = New LibraryPanelBarItemCollection
End Sub
End Class

Public Class LibraryPanelBarItemCollection
Inherits CollectionBase

Default Public ReadOnly Property Item(Index As Integer) As LibraryPanelBarItem
    Get
        Return DirectCast(List(Index), LibraryPanelBarItem)
    End Get
End Property

Public Function Contains(itemType As LibraryPanelBarItem) As Boolean
    Return List.Contains(itemType)
End Function

Public Function Add(itemType As LibraryPanelBarItem) As Integer
    Return List.Add(itemType)
End Function

Public Sub Remove(itemType As LibraryPanelBarItem)
    List.Remove(itemType)
End Sub

Public Sub Insert(index As Integer, itemType As LibraryPanelBarItem)
    List.Insert(index, itemType)
End Sub

Public Function IndexOf(itemType As LibraryPanelBarItem) As Integer
    Return List.IndexOf(itemType)
End Function

Public Sub New()

End Sub
End Class

这是我当前在 aspx 文件中的声明:

 <uc1:LibraryPanelBar ID="LibraryPanelBar2" runat="server">
     <Items>
     </Items>
 </uc1:LibraryPanelBar>

【问题讨论】:

  • 首先,您是否打算让LibraryPanelBarItem 拥有可能的自身递归列表?
  • 是的,一个LibraryPanelBarItems 可以有一个LibraryPanelBarItems 的集合。我在这里尝试创建的是一种用于导航的菜单/Outlook 栏。

标签: asp.net .net vb.net user-controls


【解决方案1】:

以下内容应为您指明正确的方向。如果您需要更多详细信息,请随时发表评论。

<ToolboxData("<{0}:LibraryPanelBar runat=""server""> </{0}:LibraryPanelBar>")>
Public Class LibraryPanelBar
    Inherits HierarchicalDataBoundControl

    Private _Items As New LibraryPanelBarItemCollection()

    <PersistenceMode(PersistenceMode.InnerProperty)> _
    <MergableProperty(False)> _
    <Editor("WebApplicationVB1.TreeNodeCollectionEditor,WebApplicationVB1", GetType(UITypeEditor))> _
    Public ReadOnly Property Items As LibraryPanelBarItemCollection
        Get
            Return _Items
        End Get
    End Property

    Protected Overrides Sub PerformSelect()

    End Sub

    Protected Overrides Sub ValidateDataSource(dataSource As Object)

    End Sub

    Protected Overrides Sub RenderContents(writer As System.Web.UI.HtmlTextWriter)
        writer.RenderBeginTag(HtmlTextWriterTag.Ul)
        For Each item As LibraryPanelBarItem In Items
            writer.RenderBeginTag(HtmlTextWriterTag.Li)
            RenderContentsRecursive(writer, item)
            writer.RenderEndTag() ' Li
        Next
        writer.RenderEndTag() ' Ul
    End Sub
    Private Sub RenderContentsRecursive(writer As System.Web.UI.HtmlTextWriter, item As LibraryPanelBarItem)
        writer.Write(item.Text)
        writer.WriteBreak()
        writer.RenderBeginTag(HtmlTextWriterTag.Ul)
        For Each subItem As LibraryPanelBarItem In item.Items
            writer.RenderBeginTag(HtmlTextWriterTag.Li)
            RenderContentsRecursive(writer, subItem)
            writer.RenderEndTag() ' Li
        Next
        writer.RenderEndTag() ' Ul
    End Sub
End Class

<ParseChildren(True, "Items")> _
Public Class LibraryPanelBarItem
    Implements IStateManager, ICloneable

    Private _Items As New LibraryPanelBarItemCollection()

    <BindableAttribute(True)> _
    Public Property ImageUrl As String

    <BindableAttribute(True)> _
    Public Property NavigateUrl As String
    Public Property Text As String
    Public Property Disabled As Boolean
    <Browsable(False)> _
<PersistenceMode(PersistenceMode.InnerDefaultProperty)> _
    Public ReadOnly Property Items As LibraryPanelBarItemCollection
        Get
            Return _Items
        End Get
    End Property
    Public ReadOnly Property HasChildren() As Boolean
        Get
            If Items.Count > 0 Then
                Return True
            Else
                Return False
            End If
        End Get
    End Property

    Public ReadOnly Property IsTrackingViewState As Boolean Implements System.Web.UI.IStateManager.IsTrackingViewState
        Get
            Throw New NotImplementedException()
        End Get
    End Property

    Public Sub LoadViewState(state As Object) Implements System.Web.UI.IStateManager.LoadViewState
        Throw New NotImplementedException()
    End Sub

    Public Function SaveViewState() As Object Implements System.Web.UI.IStateManager.SaveViewState
        Throw New NotImplementedException()
    End Function

    Public Sub TrackViewState() Implements System.Web.UI.IStateManager.TrackViewState
        Throw New NotImplementedException()
    End Sub

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Throw New NotImplementedException()
    End Function
End Class

Public Class LibraryPanelBarItemCollection
    Inherits CollectionBase
    Implements IStateManager

    Default Public ReadOnly Property Item(Index As Integer) As LibraryPanelBarItem
        Get
            Return DirectCast(List(Index), LibraryPanelBarItem)
        End Get
    End Property

    Public Function Contains(itemType As LibraryPanelBarItem) As Boolean
        Return List.Contains(itemType)
    End Function

    Public Function Add(itemType As LibraryPanelBarItem) As Integer
        Return List.Add(itemType)
    End Function

    Public Sub Remove(itemType As LibraryPanelBarItem)
        List.Remove(itemType)
    End Sub

    Public Sub Insert(index As Integer, itemType As LibraryPanelBarItem)
        List.Insert(index, itemType)
    End Sub

    Public Function IndexOf(itemType As LibraryPanelBarItem) As Integer
        Return List.IndexOf(itemType)
    End Function

    Public ReadOnly Property IsTrackingViewState As Boolean Implements System.Web.UI.IStateManager.IsTrackingViewState
        Get
            Throw New NotImplementedException()
        End Get
    End Property

    Public Sub LoadViewState(state As Object) Implements System.Web.UI.IStateManager.LoadViewState
        Throw New NotImplementedException()
    End Sub

    Public Function SaveViewState() As Object Implements System.Web.UI.IStateManager.SaveViewState
        Throw New NotImplementedException()
    End Function

    Public Sub TrackViewState() Implements System.Web.UI.IStateManager.TrackViewState
        Throw New NotImplementedException()
    End Sub
End Class

Public Class LibraryPanelBarItemCollectionEditor
    Inherits System.Drawing.Design.UITypeEditor

    Public Overrides Function EditValue(context As System.ComponentModel.ITypeDescriptorContext, provider As System.IServiceProvider, value As Object) As Object
        Return MyBase.EditValue(context, provider, value)
    End Function

    Public Overrides Function GetEditStyle(context As System.ComponentModel.ITypeDescriptorContext) As System.Drawing.Design.UITypeEditorEditStyle
        Return MyBase.GetEditStyle(context)
    End Function

End Class

编辑:添加了 UI 集合编辑器示例。

【讨论】:

  • 请注意,对于设计时集合编辑器,您需要将 EditorAttribute 添加到 Items 属性,并且需要创建自己的编辑器类,类似于:msdn.microsoft.com/en-us/library/…
  • 为上面的评论添加了示例。请注意,您需要更改 WebApplicationVB1.TreeNodeCollectionEditor 以指向您自己的命名空间。
猜你喜欢
  • 1970-01-01
  • 2010-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-18
  • 2015-01-03
相关资源
最近更新 更多