Унаследованный текст кнопки по умолчанию - PullRequest
2 голосов
/ 17 июня 2019

Это код моего унаследованного элемента управления Button:

Public Class ButtonRefreshSmall
Inherits Button

Public Sub New()
    MyBase.New
    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    Me.SuspendLayout()
    Me.Text = ""
    MyBase.Text = ""
    Me.ResumeLayout()
End Sub
End Class

Однако, когда я перестраиваю и перетаскиваю эту кнопку в форму, текст всегда ButtonRefreshSmall1. Я пробовал варианты без объявления Inherits (поскольку он уже находится в файле .Designer.vb, я попытался установить Text в режиме конструктора / классе элемента управления, но безрезультатно.
Иногда он даже не отображается в панели инструментов после перестройки.

Все, что я хочу, это чтобы текст кнопки был пустым (поскольку в конструкторе определен Image).

Это то, что у меня есть в файле Designer:

 <System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent()
    Me.SuspendLayout()
    '
    'ButtonRefreshSmall
    '
    Me.BackColor = System.Drawing.Color.Transparent
    Me.FlatAppearance.BorderSize = 0
    Me.FlatStyle = System.Windows.Forms.FlatStyle.Flat
    Me.Image = Global.TraxCashFlow.My.Resources.Resources.Refresh_grey_16x
    Me.Size = New System.Drawing.Size(23, 23)
    Me.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText
    Me.UseVisualStyleBackColor = False
    'MyBase.Text = ""
    Me.ResumeLayout(False)

End Sub

И все остальные свойства установлены так, как я их установил. Я пытался обмануть его с помощью TextImageRelation, но буква «В» всегда видна.

Обновление: Джими дал мне идею в комментарии под своим ответом, поэтому я добавил новый Property MyText, и это работает точно так же, как я хочу (хотя я не уверен, почему мне нужно звонить Refresh, если я не обновляется после потери фокуса):

Imports System.ComponentModel

Public Class ButtonRefreshSmall

Public Property MyText As String
    Get
        Return Me.Text
    End Get
    Set(value As String)
        Me.Text = value
        Me.Refresh()
    End Set
End Property

Public Sub New()
    'MyBase.New
    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    'Me.Text = ""
End Sub

<Browsable(False)>
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
Public Overrides Property Text As String
End Class

Обновление № 2, см. Ответ @ TnTinMn.

Ответы [ 3 ]

2 голосов
/ 17 июня 2019

Простой способ: переопределить или скрыть свойство Text, добавив атрибут DesignerSerializationVisibility , установив для него значение DesignerSerializationVisibility.Hidden и атрибут Browsable для False,

Конструктор не будет генерировать какой-либо код для свойства Text (поэтому элемент управления не будет отображать текст), свойство не отображается в PropertyGrid, но оно все еще существует и может быть установлено в коде.

<Browsable(False)>
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
Public Overrides Property Text As String
' or
' Public Shadows Property Text As String

Другим способом является удаление свойства с помощью пользовательского конструктора.
Смотрите здесь, как его можно реализовать:
Можно ли изменить значение атрибута свойстваво время проектирования?

2 голосов
/ 17 июня 2019

Для достижения цели, указанной вами в комментарии к принятому ответу,

... Я бы хотел, чтобы свойство Text оставалось, но оставалось пустым ...

Вы можете применить ToolboxItemAttribute к своему пользовательскому классу кнопок.

<System.ComponentModel.ToolboxItemAttribute(GetType(ToolBoxItemNoDefaultText))>
Public Class ButtonRefreshSmall

Это скажет среде разработки использовать класс ToolBoxItemNoDefaultText для управления созданием ButtonRefreshSmall для размещения на дизайнерской поверхности.ToolBoxItemNoDefaultText будет производным от ToolboxItem Class .

Imports System.Drawing.Design
Imports System.ComponentModel
Imports System.Runtime.Serialization
Imports System.Windows.Forms

<Serializable()> ' ToolBoxItems must be Serializable 
Public Class ToolBoxItemNoDefaultText : Inherits ToolboxItem
  Public Sub New(ByVal toolType As Type)
    ' this constructor is needed to allow the type decorated with 
    ' <System.ComponentModel.ToolboxItemAttribute(GetType(ToolBoxItemNoDefaultText))>
    ' to be added to the ToolBox
    MyBase.New(toolType)
  End Sub

  Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
    ' this constructor is needed to support the design-time deserialization of this
    ' class by the design environment.
    Deserialize(info, context)
  End Sub

  Protected Overrides Sub OnComponentsCreated(args As ToolboxComponentsCreatedEventArgs)
    ' this will run after all initialization code has run including that set
    ' by the component's designer, thus you can override designer set values.
    For Each comp As IComponent In args.Components
      Dim ctrl As Control = TryCast(comp, Control)
      If ctrl IsNot Nothing Then ctrl.Text = String.Empty
    Next
    MyBase.OnComponentsCreated(args)
  End Sub
End Class

Это решение несколько устарело, поскольку позволяет запускать код конструктора по умолчанию, а затем изменяет созданный экземпляр.Вы можете заметить, что значение Text, установленное дизайнером, на мгновение отображается перед тем, как оно будет установлено на String.Empty.

Надлежащим способом решения этой проблемы является создание собственного конструктора и не установка свойства Text во время инициализации.Тем не менее, правильная реализация пользовательского конструктора может быть задействована, если пользовательский интерфейс должен быть как можно ближе к тому, который реализован MS.

2 голосов
/ 17 июня 2019

Это то, что делает дизайнер WinForms. Когда вы добавляете элемент управления в форму, он устанавливает свойства Name и Text в зависимости от типа элемента управления и их количества в форме с именами по умолчанию. Это делается после выполнения конструктора, поэтому ваш код конструктора не может помочь. Вам нужно было бы поместить код в само свойство, чтобы игнорировать набор в конструкторе:

Public Overrides Property Text As String
    Get
        Return MyBase.Text
    End Get
    Set
        If Not DesignMode Then
            MyBase.Text = Value
        End If
    End Set
End Property

Обратите внимание, что это означает, что вы также не сможете установить его самостоятельно, кроме как во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...