我一直在研究这个问题,我得到的两个最广泛持有的想法是:1)将 ToolStrip 作为属性公开。2) 为 UserControl 使用 ControlDesigner 并为 ToolStrip 设置 EnableDesignMode。
但不知何故,它们都没有真正达到我的目的,因为暴露 ToolStrip 会让用户完全控制它,这不是我的目标。第二个选项甚至会让用户删除 ToolStrip。因此,我不得不想出一种不同的方法。那是我绊倒 CollectionBase 类的时候。
正如它所说,CollectionBase 类是强类型集合的抽象基类。那么如何通过它来维护 ToolStrip 项集合呢?我创建了一个CollectionBase类的实例,并通过它来规范ToolStrip项的添加、修改、获取和删除。集合中的每个项目都来自从 ToolStripButton 类继承的类。这样,单个项目可以作为任何标准 ToolStripButton 处理,您可以相应地向用户隐藏或显示属性。最后,有问题的 ToolStrip 被设置为 CollectionBase 的父级,最终也成为每个 ToolStripItem 的父级。这是概念:
Imports System.ComponentModel
Imports System.Windows.Forms
Imports Office2003
Imports System.Drawing
Imports System.Windows.Forms.Design
Public Class MyUserControl
Private _Buttons As MyUserControlButtons
Public Event MyUserControlButtonClicked(ByVal Sender As MyUserControlButton)
Public Sub New()
MyBase.New()
'This call is required by the Component Designer.
InitializeComponent()
_Buttons = New MyUserControlButtons(MyToolStrip)
End Sub
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
Public ReadOnly Property Buttons As MyUserControlButtons
Get
Return _Buttons
End Get
End Property
Private Sub MyToolStrip_ItemClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles MyToolStrip.ItemClicked
'Check if the ToolStrip item clicked is a ToolStripButton...
If TypeOf e.ClickedItem Is ToolStripButton Then
'Insert your code here...
'Raise the custom event.
RaiseEvent MyUserControlButtonClicked(Item)
End If
End Sub
End Class
#Region "Manager classes for MyUserControl buttons."
Public Class MyUserControlButtons
Inherits CollectionBase
Private _Parent As ToolStrip
''' <summary>
''' Initializes a new instance of the MyUserControlButtons class.
''' </summary>
''' <param name="Holder">The ToolStrip that contains the items of the MyUserControlButtons class.</param>
Public Sub New(ByVal Holder As ToolStrip)
MyBase.New()
_Parent = Holder
End Sub
''' <summary>
''' The ToolStrip that contains this item.
''' </summary>
Public ReadOnly Property Parent() As ToolStrip
Get
Return _Parent
End Get
End Property
''' <summary>
''' Gets the element at the specified index.
''' </summary>
''' <param name="Index">The zero-based index of the element to get.</param>
Default Public ReadOnly Property Item(ByVal Index As Integer) As MyUserControlButton
Get
Return CType(List(Index), MyUserControlButton)
End Get
End Property
''' <summary>
''' Adds an item to the collection.
''' </summary>
Public Function Add() As MyUserControlButton
Return Me.Add
End Function
''' <summary>
''' Adds an item to the collection.
''' </summary>
''' <param name="Value">The object to add to the collection.</param>
Public Sub Add(ByVal Value As MyUserControlButton)
List.Add(Value)
Value.Parent = Me.Parent
End Sub
''' <summary>
''' Adds an item to the collection.
''' </summary>
''' <param name="Name">The name of the object to add to the collection.</param>
''' <param name="Image">The image of the object to add to the collection.</param>
Public Function Add(ByVal Name As String, ByVal Image As Image) As MyUserControlButton
Dim b As MyUserControlButton = New MyUserControlButton(Me.Parent)
b.Name = Name
b.Text = Name
b.Image = Image
Me.Add(b)
Return b
End Function
''' <summary>
''' Adds an item to the collection.
''' </summary>
''' <param name="Name">The name of the object to add to the collection.</param>
''' <param name="Text">The text of the object to add to the collection.</param>
''' <param name="Image">The image of the object to add to the collection.</param>
Public Function Add(ByVal Name As String, ByVal Text As String, ByVal Image As Image) As MyUserControlButton
Dim b As MyUserControlButton = New MyUserControlButton(Me.Parent)
b.Name = Name
b.Text = Text
b.Image = Image
Me.Add(b)
Return b
End Function
''' <summary>
''' Removes the first occurence of a specific object from the collection.
''' </summary>
''' <param name="Value">The object to be removed.</param>
Public Sub Remove(ByVal Value As MyUserControlButton)
List.Remove(Value)
End Sub
''' <summary>
''' Determines the index of a specific item in the collection.
''' </summary>
''' <param name="Value">The object to locate in the collection.</param>
Public Function IndexOf(ByVal Value As Object) As Integer
Return List.IndexOf(Value)
End Function
''' <summary>
''' Determines whether the collection contains a specific value.
''' </summary>
''' <param name="Value">The object to locate in the collection.</param>
Public Function Contains(ByVal Value As MyUserControlButton) As Boolean
Return List.Contains(Value)
End Function
Protected Overrides Sub OnInsertComplete(ByVal index As Integer, ByVal value As Object)
Dim b As MyUserControlButton = CType(value, MyUserControlButton)
b.Parent = Me.Parent
Me.Parent.Items.Insert(index, CType(value, ToolStripButton))
MyBase.OnInsertComplete(index, value)
End Sub
Protected Overrides Sub OnSetComplete(ByVal index As Integer, ByVal oldValue As Object, ByVal newValue As Object)
Dim b As MyUserControlButton = CType(newValue, MyUserControlButton)
b.Parent = Me.Parent
MyBase.OnSetComplete(index, oldValue, newValue)
End Sub
Protected Overrides Sub OnClearComplete()
MyBase.OnClearComplete()
End Sub
End Class
Public Class MyUserControlButton
Inherits ToolStripButton
''' <summary>
''' Initializes a new instance of the MyUserControlButton class.
''' </summary>
Sub New()
MyBase.New()
Init()
End Sub
''' <summary>
''' Initializes a new instance of the MyUserControlButton class.
''' </summary>
''' <param name="Holder">The ToolStrip that contains the StackView button.</param>
Sub New(ByVal Holder As ToolStrip)
MyBase.New()
Init()
Me.Parent = Holder
End Sub
Private Sub Init()
Me.AutoToolTip = False
Me.DisplayStyle = ToolStripItemDisplayStyle.ImageAndText
Me.ImageAlign = ContentAlignment.MiddleLeft
Me.ImageIndex = -1
Me.ImageKey = ""
Me.ImageTransparentColor = Color.Magenta
Me.TextAlign = ContentAlignment.MiddleLeft
Me.TextDirection = ToolStripTextDirection.Horizontal
End Sub
''' <remarks>
''' Hide this property from the user in both design and code editor.
''' </remarks>
<Browsable(False),
EditorBrowsable(False)> _
Public Shadows Property AccessibleDefaultActionDescription As String
Get
Return MyBase.AccessibleDefaultActionDescription
End Get
Set(ByVal value As String)
MyBase.AccessibleDefaultActionDescription = value
End Set
End Property
''' <remarks>
''' Hide this property from the user in both design and code editor.
''' </remarks>
<Browsable(False),
EditorBrowsable(False)> _
Public Shadows Property AccessibleDescription As String
Get
Return MyBase.AccessibleDescription
End Get
Set(ByVal value As String)
MyBase.AccessibleDescription = value
End Set
End Property
''' <remarks>
''' Hide this property from the user in both design and code editor.
''' </remarks>
<Browsable(False),
EditorBrowsable(False)> _
Public Shadows Property AccessibleName As String
Get
Return MyBase.AccessibleName
End Get
Set(ByVal value As String)
MyBase.AccessibleName = value
End Set
End Property
' Keep on hiding the irrelevant properties...
''' <summary>
''' Gets or sets a value indicating whether default or custom ToolTip text is displayed on the ToolStripButton.
''' </summary>
<DefaultValue(False)> _
Public Shadows Property AutoToolTip As Boolean
Get
Return MyBase.AutoToolTip
End Get
Set(ByVal value As Boolean)
MyBase.AutoToolTip = value
End Set
End Property
''' <summary>
''' Specifies whether the image and text are rendered.
''' </summary>
<DefaultValue(GetType(ToolStripItemDisplayStyle), "ImageAndText")> _
Public Overrides Property DisplayStyle As System.Windows.Forms.ToolStripItemDisplayStyle
Get
Return MyBase.DisplayStyle
End Get
Set(ByVal value As System.Windows.Forms.ToolStripItemDisplayStyle)
MyBase.DisplayStyle = value
End Set
End Property
''' <summary>
''' The image that will be displayed on the control.
''' </summary>
Public Overrides Property Image() As Image
Get
Return MyBase.Image
End Get
Set(ByVal value As Image)
MyBase.Image = value
End Set
End Property
''' <summary>
''' Gets or sets the alignment of the image on a ToolStripItem.
''' </summary>
<DefaultValue(GetType(ContentAlignment), "MiddleLeft")> _
Public Shadows Property ImageAlign As ContentAlignment
Get
Return MyBase.ImageAlign
End Get
Set(ByVal value As ContentAlignment)
MyBase.ImageAlign = value
End Set
End Property
<EditorBrowsable(False),
DefaultValue(-1)> _
Public Shadows Property ImageIndex As Integer
Get
Return MyBase.ImageIndex
End Get
Set(ByVal value As Integer)
MyBase.ImageIndex = value
End Set
End Property
<EditorBrowsable(False),
DefaultValue("")> _
Public Shadows Property ImageKey As String
Get
Return MyBase.ImageKey
End Get
Set(ByVal value As String)
MyBase.ImageKey = value
End Set
End Property
''' <summary>
''' Gets or sets the color to treat as transparent in a ToolStripItem image.
''' </summary>
Public Shadows Property ImageTransparentColor As Color
Get
Return MyBase.ImageTransparentColor
End Get
Set(ByVal value As Color)
MyBase.ImageTransparentColor = value
End Set
End Property
''' <summary>
''' Specifies the name used to identify the object.
''' </summary>
Public Shadows Property Name() As String
Get
Return MyBase.Name
End Get
Set(ByVal value As String)
MyBase.Name = value
End Set
End Property
''' <summary>
''' The ToolStrip that contains this item.
''' </summary>
<Browsable(False)> _
Public Shadows Property Parent As ToolStrip
Get
Return MyBase.Parent
End Get
Set(ByVal value As ToolStrip)
MyBase.Parent = value
End Set
End Property
''' <summary>
''' The text that will be displayed on the control.
''' </summary>
Public Overrides Property Text() As String
Get
Return MyBase.Text
End Get
Set(ByVal value As String)
MyBase.Text = value
End Set
End Property
''' <summary>
''' Gets or sets the alignment of the text on a ToolStripLabel.
''' </summary>
<DefaultValue(GetType(ContentAlignment), "MiddleLeft")> _
Public Overrides Property TextAlign As ContentAlignment
Get
Return MyBase.TextAlign
End Get
Set(ByVal value As ContentAlignment)
MyBase.TextAlign = value
End Set
End Property
<Browsable(False),
EditorBrowsable(False),
DefaultValue(GetType(ToolStripTextDirection), "Horizontal")> _
Public Overrides Property TextDirection As ToolStripTextDirection
Get
Return MyBase.TextDirection
End Get
Set(ByVal value As ToolStripTextDirection)
MyBase.TextDirection = value
End Set
End Property
' Define other properties accordingly...
End Class
#End Region
MyUserControl 是包含名为 MyToolStrip 的 ToolStrip 的自定义用户控件。MyUserControlButtons 是继承自 CollectionBase 的类,而 MyUserControlButtons 的每一项都是继承自 ToolStripButton 的 MyUserControlButton 类的对象。
在 MyUserControl 的构造函数中,MyUserControlButtons 以 MyToolStrip 作为其父对象进行实例化。通过从 MyUserControlButton 创建新对象,将项目添加到 MyUserControlButtons。要隐藏或显示的项目的属性在 MyUserControlButton 中进行管理。MyUserControl 通过只读属性“Buttons”返回按钮列表。请注意“Buttons”属性的 DesignerSerializationVisibility 属性。它指定在设计时序列化组件上的属性时要使用的持久性类型。“内容”枚举成员告诉代码生成器为对象的内容生成代码,而不是为对象本身生成代码。
这种方法的缺点是在 UserControl 上执行复制粘贴时无法保留 ToolStrip 的项目。它仅在用户明确处理项目而不是在复制粘贴期间对内容进行序列化。任何关于如何处理它的想法都受到高度赞赏。
感谢所有的海报。尽管我应用了自己的概念,但您的想法为我铺平了道路。