默认继承的按钮文本
Default inherited button text
这是我继承的 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
文件中,我试过在控件的 Designer view/class 中设置 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
来欺骗它,但无论如何 "B" 总是可见的。
更新:Jimi 在他的回答下方的评论中给了我这个想法,所以我添加了一个新的 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 的回答。
这正是 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
请注意,这意味着您也无法自行设置,除非在 run-time。
简单方法:覆盖或隐藏文本 属性,将 DesignerSerializationVisibility Attribute, setting it to DesignerSerializationVisibility.Hidden
and the Browsable 属性添加到 False
。
Designer 不会为文本 属性 生成任何代码(因此控件不会显示文本),属性 在 PropertyGrid 中不可见,但它仍然存在并且可以在代码中设置。
<Browsable(False)>
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
Public Overrides Property Text As String
' or
' Public Shadows Property Text As String
另一种方法是使用自定义设计器删除 属性。
在这里查看它是如何实现的:
为了实现您在已接受答案的评论中所述的目标,
... I'd want Text property to remain but just to be empty ...
您可以将 ToolboxItemAttribute 应用于您的自定义按钮 class。
<System.ComponentModel.ToolboxItemAttribute(GetType(ToolBoxItemNoDefaultText))>
Public Class ButtonRefreshSmall
这将告诉设计环境使用 class 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 实现的体验,则可能涉及自定义设计器的正确实现。
这是我继承的 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
文件中,我试过在控件的 Designer view/class 中设置 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
来欺骗它,但无论如何 "B" 总是可见的。
更新:Jimi 在他的回答下方的评论中给了我这个想法,所以我添加了一个新的 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 的回答。
这正是 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
请注意,这意味着您也无法自行设置,除非在 run-time。
简单方法:覆盖或隐藏文本 属性,将 DesignerSerializationVisibility Attribute, setting it to DesignerSerializationVisibility.Hidden
and the Browsable 属性添加到 False
。
Designer 不会为文本 属性 生成任何代码(因此控件不会显示文本),属性 在 PropertyGrid 中不可见,但它仍然存在并且可以在代码中设置。
<Browsable(False)>
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
Public Overrides Property Text As String
' or
' Public Shadows Property Text As String
另一种方法是使用自定义设计器删除 属性。
在这里查看它是如何实现的:
为了实现您在已接受答案的评论中所述的目标,
... I'd want Text property to remain but just to be empty ...
您可以将 ToolboxItemAttribute 应用于您的自定义按钮 class。
<System.ComponentModel.ToolboxItemAttribute(GetType(ToolBoxItemNoDefaultText))>
Public Class ButtonRefreshSmall
这将告诉设计环境使用 class 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 实现的体验,则可能涉及自定义设计器的正确实现。