簡體   English   中英

如何在自定義 UserControl(.Net 4、Winforms)上使用項目集合編輯器?

[英]How to use an Items Collection Editor on a custom UserControl (.Net 4, Winforms)?

我創建了一個包含自定義ToolStrip ControlUserControl 在整個應用程序中使用UserControl ,不能直接訪問ToolStrip控件,因為它在邏輯上嵌入在UserControl

因此,為了訪問ToolStrip的項目,我在UserControl類中定義了一個readonly屬性,該屬性返回 ToolStrip 的項目。

現在,可以使用UserControl.Items屬性以編程方式編輯ToolStrip的項目,但我無法在設計模式下執行相同操作。

就像有人將UserControlToolBox拖到窗體上,轉到propertyGrid ,選擇 Item 的屬性並相應地操作根深蒂固的ToolStrip的項目; 就像我們在項目Collection Editor的幫助下處理任何標准ToolStrip控件的項目集合一樣。

這里,雖然UserControlItems屬性顯示在propertyGrid ,但它不可用,每次單擊時都會顯示錯誤消息

值不能為空。 參數名稱:值

我確定這是因為該屬性被聲明為只讀,我需要更多地加息,以便在 propertyGrid 中單擊它時,Items Collection Editor彈出ToolStrip的項目,因此可以進行處理。

那么我該怎么做呢?

您可以通過公開ToolStrip本身來做到這一點,但這不是一個好主意。 UserControl不應公開其內部控件。

如果您的用戶控件只有一個ToolStrip您應該考慮使用CustomControl ,它是一個繼承ToolStrip的類,您可以免費獲得其所有功能,包括設計功能。

我一直在研究這個問題一段時間,我得到的兩個最廣泛的想法是: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 屬性。 它指定在設計時序列化組件上的屬性時要使用的持久性類型。 “Content”枚舉成員告訴代碼生成器為對象的內容生成代碼,而不是為對象本身生成代碼。

這種方法的缺點是您不能在對 UserControl 執行復制粘貼時保留 ToolStrip 的項目。 它僅在用戶明確處理項目時而不是在復制粘貼期間序列化內容。 任何關於如何處理它的想法都受到高度贊賞。

感謝所有海報。 雖然我應用了我自己的概念,但你的想法為我鋪平了道路。

我有一個解決方案,但對於 c#

        [Editor("System.ComponentModel.Design.CollectionEditor, System.Design", typeof(UITypeEditor))]
    [MergableProperty(false)]
    [Category("Data")]
    [DescriptionAttribute("ToolStripItems")]
    public virtual ToolStripItemCollection ToolstripItems
    {
        get => toolStrip.Items;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM