Electro_Attacks Ответов: 1

Как я могу исправить заполнение моего нового tabcontrol?


Мне нужен был TabControl с CloseButton, я нашел несколько фрагментов и сделал их в соответствии с моими личными пожеланиями, например, множество вариантов и дизайн метро... Как уже упоминалось во многих потоках, tabpagecontrol не имеет рабочего свойства ItemSize или, по крайней мере, очень глючит, вместо этого вы должны использовать свойство padding, чтобы все было хорошо выровнено...
Теперь проблема заключается в следующем: когда я изменяю свойство TabPadding в своем исходном коде, все это будет отображаться так, как я хотел, но как только я изменю его в окне конструктора моей тестовой формы, все мои кнопки закрытия исчезнут... Они все еще находятся в коллекциях, но я не могу заставить их появиться снова. Вот мой код:

<pre>Public Class MetroTabControlEx
    Inherits MetroTabControl

    Private Declare Auto Function SetParent Lib "user32" (ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr
    Protected CloseButtonCollection As New Dictionary(Of MetroTile, MetroTabPage)
    Protected HiddenButtonCollection As New Dictionary(Of MetroTile, MetroTabPage)

    Private _ShowOnTabs As Boolean = True
    Private _ShowOnAllTabs As Boolean = False
    Private _WithoutButtonTabs As Integer = 0

    Private _TabPadding As Point = New Point(20, 30)
    Private _DefaultSize As Size = New Size(16, 16)
    Private _SelectedSize As Size = New Size(20,20)

    Private _UseTileImage As Boolean = True
    Private _ButtonImage As Image = My.Resources.CloseTab
    Private _ButtonText As String = ""

    Private _UseStyleColors As Boolean = False
    Private _ButtonStyleManager As MetroStyleManager = Nothing

    Private _ButtonStyle As MetroColorStyle = MetroColorStyle.Red
    Private _ButtonTheme As MetroThemeStyle = MetroThemeStyle.Default
    
    Private _UseCustomBackColor As Boolean = False
    Private _CustomBackColor As Color = Color.Transparent

    Private _UseCustomForeColor As Boolean = False
    Private _CustomForeColor As Color = Color.Black


    ' Buttons: Show
    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("Close buttons on each MetroTabPage")> _
    Public Property ShowOnTabs() As Boolean
        Get
            Return _ShowOnTabs
        End Get
        Set(ByVal value As Boolean)
            _ShowOnTabs = value
            RePositionCloseButtons()
        End Set
    End Property

    ' Buttons: Show on All Tabs
    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("Close buttons on all MetroTabPage")> _
    Public Property ShowOnAllTabs() As Boolean
        Get
            Return _ShowOnAllTabs
        End Get
        Set(ByVal value As Boolean)
            _ShowOnAllTabs = value
            RePositionCloseButtons()
        End Set
    End Property

    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("TabPages (0 - x) without Button")> _
    Public Property WithoutButtonTabs() As Integer
        Get
            Return _WithoutButtonTabs
        End Get
        Set
            _WithoutButtonTabs = Value
            RePositionCloseButtons()
        End Set
    End Property

    ' Buttons: Tab Padding
    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("Tab Padding")> _
    Public Property TabPadding() As Point
        Get
            Return _TabPadding
        End Get
        Set(ByVal value As Point)
            _TabPadding = value
            ChangePadding()
        End Set 
    End Property


    ' Buttons: Default Size
    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("Default Button Size")> _
    Public Property DefaultSize() As Size
        Get
            Return _DefaultSize
        End Get
        Set(ByVal value As Size)
            _DefaultSize = value
            For Each btn In CloseButtonCollection.Keys
                btn.Size = _DefaultSize
            Next
            RePositionCloseButtons()
        End Set
    End Property

    ' Buttons: Selected Size
    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("Selected Tab Button Size")> _
    Public Property SelectedSize() As Size
        Get
            Return _SelectedSize
        End Get
        Set(ByVal value As Size)
            _SelectedSize = value
            RePositionCloseButtons()
        End Set
    End Property


    ' Buttons: Use Tile Image
    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("Use Tile Image")> _
    Public Property UseTileImage() As Boolean
        Get
            Return _UseTileImage
        End Get
        Set(ByVal value As Boolean)
            _UseTileImage = value
            RePositionCloseButtons()
        End Set
    End Property

    ' Buttons: Tile Image
    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("Button Image")> _
    Public Property ButtonImage() As Image
        Get
            Return _ButtonImage
        End Get
        Set(ByVal value As Image)
            _ButtonImage = value
            RePositionCloseButtons()
        End Set
    End Property

    ' Buttons: Tile Text
    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("Button Text")> _
    Public Property ButtonText() As String
        Get
            Return _ButtonText
        End Get
        Set(ByVal value As String)
            _ButtonText = value
            RePositionCloseButtons()
        End Set
    End Property


    ' Buttons: Style Manager
    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("Button Style Manager")> _
    Public Property ButtonStyleManager() As MetroStyleManager
        Get
            Return _ButtonStyleManager
        End Get
        Set(ByVal value As MetroStyleManager)
            _ButtonStyleManager = value
            RePositionCloseButtons()
        End Set
    End Property


    ' Buttons: Use Style Colors
    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("Use Style Colors")> _
    Public Property UseStyleColors() As Boolean
        Get
            Return _UseStyleColors
        End Get
        Set(ByVal value As Boolean)
            _UseStyleColors = value
            RePositionCloseButtons()
        End Set
    End Property

    ' Buttons: Metro Style
    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("Metro Style")> _
    Public Property ButtonStyle() As MetroColorStyle
        Get
            Return _ButtonStyle
        End Get
        Set(ByVal value As MetroColorStyle)
            _ButtonStyle = value
            RePositionCloseButtons()
        End Set
    End Property

    ' Buttons: Metro Theme
    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("Metro Theme")> _
    Public Property ButtonTheme() As MetroThemeStyle
        Get
            Return _ButtonTheme
        End Get
        Set(ByVal value As MetroThemeStyle)
            _ButtonTheme = value
            RePositionCloseButtons()
        End Set
    End Property


    ' Buttons: Use Custom BackColor
    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("Use Custom BackColor")> _
    Public Property UseCustomBackColor() As Boolean
        Get
            Return _UseCustomBackColor
        End Get
        Set(ByVal value As Boolean)
            _UseCustomBackColor = value
            RePositionCloseButtons()
        End Set
    End Property

    ' Buttons: Cutsom BackColor
    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("Custom BackColor")> _
    Public Property CustomBackColor() As Color
        Get
            Return _CustomBackColor
        End Get
        Set(ByVal value As Color)
            _CustomBackColor = value
            RePositionCloseButtons()
        End Set
    End Property


    ' Buttons: Use Custom ForeColor
    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("Use Custom ForeColor")> _
    Public Property UseCustomForeColor() As Boolean
        Get
            Return _UseCustomForeColor
        End Get
        Set(ByVal value As Boolean)
            _UseCustomForeColor = value
            RePositionCloseButtons()
        End Set
    End Property

    ' Buttons: Cutsom ForeColor
    <Browsable(True), DefaultValue(True), Category("Close Button"), Description("Custom ForeColor")> _
    Public Property CustomForeColor() As Color
        Get
            Return _CustomForeColor
        End Get
        Set(ByVal value As Color)
            _CustomForeColor = value
            RePositionCloseButtons()
        End Set
    End Property

    Protected Overrides Sub OnCreateControl()
        MyBase.OnCreateControl()
        RePositionCloseButtons()
    End Sub

    Protected Overrides Sub OnControlAdded(ByVal e As System.Windows.Forms.ControlEventArgs)
        
        MyBase.OnControlAdded(e)
        ChangePadding()
        Dim tp As MetroTabPage = DirectCast(e.Control, MetroTabPage)
        Dim tpIndex As Integer = Me.TabPages.IndexOf(tp)
        Dim btn As MetroTile = AddCloseButton(tp)

        btn.Size = New Size(_DefaultSize.Width, _DefaultSize.Height)
        Dim rect As Rectangle = Me.GetTabRect(tpIndex)
        btn.Location = New Point(rect.X + rect.Width - rect.Height - 1, rect.Y + 1)

        SetParent(btn.Handle, Me.Handle)
        AddHandler btn.Click, AddressOf OnCloseButtonClick
        CloseButtonCollection.Add(btn, tp)
    End Sub

    Protected Overrides Sub OnControlRemoved(ByVal e As System.Windows.Forms.ControlEventArgs)
        Dim cbtn As MetroTile = CloseButtonOfTabPage(DirectCast(e.Control, MetroTabPage))
        Dim hbtn As MetroTile = HiddenButtonOfTabPage(DirectCast(e.Control, MetroTabPage))
        RemoveHandler cbtn.Click, AddressOf OnCloseButtonClick
        CloseButtonCollection.Remove(cbtn)
        If hbtn IsNot Nothing Then HiddenButtonCollection.Remove(hbtn)
        SetParent(cbtn.Handle, Nothing)
        cbtn.Dispose()
        MyBase.OnControlRemoved(e)
    End Sub

    Protected Overrides Sub OnLayout(ByVal levent As System.Windows.Forms.LayoutEventArgs)
        MyBase.OnLayout(levent)
        RePositionCloseButtons()
    End Sub

    Public Event CloseButtonClick As CancelEventHandler
    Protected Overridable Sub OnCloseButtonClick(ByVal sender As Object, ByVal e As EventArgs)
        If Not DesignMode Then
            Dim btn As MetroTile = DirectCast(sender, MetroTile)
            Dim tp As MetroTabPage = CloseButtonCollection(btn)
            Dim ee As New CancelEventArgs
            RaiseEvent CloseButtonClick(sender, ee)
            If Not ee.Cancel Then
                TabPages.Remove(tp)
                RePositionCloseButtons()
            End If
        End If
    End Sub

    Protected Overridable Function AddCloseButton(ByVal tp As MetroTabPage) As MetroTile
        Dim closeButton As New MetroTile
        With closeButton
            ' Tile Image
            .UseTileImage = _UseTileImage
            .TileImage = _ButtonImage
            .TileImageAlign = ContentAlignment.MiddleCenter

            ' Text
            .Text = _ButtonText
            .TextAlign = ContentAlignment.BottomLeft

            ' Coloring
            .StyleManager = _ButtonStyleManager
            .UseStyleColors = _UseStyleColors
            .Theme = _ButtonTheme
            .Style = _ButtonStyle

            .UseCustomBackColor = _UseCustomBackColor
            .BackColor = _CustomBackColor
            .UseCustomForeColor = _UseCustomForeColor
            .ForeColor = _CustomForeColor
        End With
        Return closeButton
    End Function

    Public Sub ChangePadding()
        If _TabPadding = New Point(0, 0) Then _TabPadding = New Point(_SelectedSize.Width, 3)
        Me.Padding = _TabPadding
        Me.Invalidate()
    End Sub




    Public Sub RePositionCloseButtons()
        For Each item In CloseButtonCollection
            RePositionCloseButtons(item.Value)
        Next
    End Sub

    Public Sub RePositionCloseButtons(ByVal tp As MetroTabPage)
        Dim btn As MetroTile = CloseButtonOfTabPage(tp)
        Dim tpIndex As Integer = Me.TabPages.IndexOf(tp)
        tp.Size = New Size(100, 10)
        If tpIndex <= _WithoutButtonTabs AndAlso Not _ShowOnAllTabs Then HideButton(tpIndex, True)
        If btn IsNot Nothing AndAlso tpIndex >= 0 Then
            Dim rect As Rectangle = Me.GetTabRect(tpIndex)
            If Me.SelectedTab Is tp Then
                With btn
                    ' Tile Image
                    .UseTileImage = _UseTileImage
                    .TileImage = _ButtonImage
                    .TileImageAlign = ContentAlignment.MiddleCenter

                    ' Text
                    .Text = _ButtonText
                    .TextAlign = ContentAlignment.BottomLeft

                    ' Coloring
                    .StyleManager = _ButtonStyleManager
                    .UseStyleColors = _UseStyleColors
                    .Theme = _ButtonTheme
                    .Style = _ButtonStyle

                    .UseCustomBackColor = _UseCustomBackColor
                    .BackColor = _CustomBackColor
                    .UseCustomForeColor = _UseCustomForeColor
                    .ForeColor = _CustomForeColor

                    .Size = New Size(_SelectedSize.Width, _SelectedSize.Height)
                    .Location = New Point(rect.X + rect.Width - btn.Width, rect.Y + 1)
                End With
            Else
                With btn
                    ' Tile Image
                    .UseTileImage = _UseTileImage
                    .TileImage = _ButtonImage
                    .TileImageAlign = ContentAlignment.MiddleCenter

                    ' Text
                    .Text = _ButtonText
                    .TextAlign = ContentAlignment.BottomLeft

                    ' Coloring
                    .StyleManager = _ButtonStyleManager
                    .UseStyleColors = _UseStyleColors
                    .Theme = _ButtonTheme
                    .Style = _ButtonStyle

                    .UseCustomBackColor = _UseCustomBackColor
                    .BackColor = _CustomBackColor
                    .UseCustomForeColor = _UseCustomForeColor
                    .ForeColor = _CustomForeColor

                    .Size = New Size(_DefaultSize.Width, _DefaultSize.Height)
                    .Location = New Point(rect.X + rect.Width - btn.Width, rect.Y + 1)
                End With
            End If
            If btn IsNot HiddenButtonOfTabPage(tp)
                btn.Visible = ShowOnTabs
                btn.BringToFront()
            End If
        End If
    End Sub

    Protected Function CloseButtonOfTabPage(ByVal tp As MetroTabPage) As MetroTile
        Return (From item In CloseButtonCollection Where item.Value Is tp Select item.Key).FirstOrDefault
    End Function


Что я уже пробовал:

Я попробовал пошевелить ChangePadding() вызов на другие мероприятия, и попытался использовать OnChangedPaddingEvent чтобы кнопки снова появились, но ничего не получалось...

Maciej Los

- Когда я изменяю свойство TabPadding в своем исходном коде... все мои кнопки закрытия исчезают". это нормальное поведение пользовательских элементов управления. Вы должны заново построить/скомпилировать проект.

[no name]

Нет, происходит обратное: когда я изменяю его в исходном коде, он появляется правильно.
Когда я изменяю его в окне конструктора они исчезают

1 Ответов

Рейтинг:
7

Maciej Los

Все атрибуты для пользовательских элементов управления перечислены здесь: Атрибуты в элементах управления - Windows Forms | Microsoft Docs[^].
Я думаю (но я не уверен), что вы должны использовать один из них:
Класс EditorAttribute (System.ComponentModel) | Microsoft Docs[^]
Класс EditorBrowsableAttribute (System.ComponentModel) | Microsoft Docs[^]
Класс RefreshPropertiesAttribute (System.ComponentModel) | Microsoft Docs[^] - выглядит очень многообещающе ;)

Удачи вам!