Reputation: 1070
This is the code for my inherited Button control:
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
However, when I rebuild and drag this button to a form the text is always ButtonRefreshSmall1
. I've tried variants without the Inherits
declaration (since it's already in the .Designer.vb
file, I've tried setting Text
in Designer view/class of the control, to no avail.
Sometimes it won't even show in the Toolbox after rebuild.
All I want is for text of the button to be empty (since it has an Image
defined in the designer).
This is what I have in the Designer file:
<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
And all other properties are set like I set them. I tried to trick it with TextImageRelation
but the "B" is always visible anyway.
Update: Jimi gave me the idea in a comment below his answer, so I added a new Property
MyText
and this works just like I want (not sure why I need to call Refresh
though, if I don't then it's updated after losing focus):
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
Update #2, see @TnTinMn's answer.
Upvotes: 3
Views: 830
Reputation: 11801
To accomplish the goal you stated in a comment to the accepted answer,
... I'd want Text property to remain but just to be empty ...
You can apply a ToolboxItemAttribute to your custom button class.
<System.ComponentModel.ToolboxItemAttribute(GetType(ToolBoxItemNoDefaultText))>
Public Class ButtonRefreshSmall
This will tell the design environment to use the class ToolBoxItemNoDefaultText
to control the creation of ButtonRefreshSmall
for placement on the design surface. ToolBoxItemNoDefaultText
will derive from the 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
This solution is somewhat after the fact as it allows the default designer code to run and then modifies the created instance. You may notice that the Text
set by the designer is momentarily displayed before it is set to String.Empty
.
The proper way to deal with this would be to create a custom designer and not set the Text
property during initialization. However, proper implementation of a custom designer can become involved if the user experience is to be as close as possible that implemented by MS.
Upvotes: 3
Reputation: 32223
Simple way: override or shadow the Text property, adding a DesignerSerializationVisibility Attribute, setting it to DesignerSerializationVisibility.Hidden
and the Browsable attribute to False
.
The Designer won't generate any code for the Text property (so the Control won't show a text), the property is not visible in the PropertyGrid but it's still there and can be set in code.
<Browsable(False)>
<DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)>
Public Overrides Property Text As String
' or
' Public Shadows Property Text As String
Another way is to remove the property, using a custom designer.
See here how it can be implemented:
Is it possible to change the value of a property attribute at design time?
Upvotes: 2
Reputation: 54417
That's just what the WinForms designer does. When you add a control to the form, it sets the Name
and Text
properties based on the type of the control and the number of them that are on the form with default names. It's done after the constructor is executed so your constructor code can't help. You'd have to put code in the property itself to ignore a set in the designer:
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
Note that that means that you won't be able to set it yourself either though, unless at run-time.
Upvotes: 2