Reputation: 23
I am positive this is something very simple, but I am having complete brain freeze.
I am trying to create my own control which will add some specific functionality to a textbox, and ultimately want this control to be available in my toolbox for use throughout my project.
As an example, I would like to add this new control to my form, change the .Text property to "Something" and then perform some logic on the .Text property in the New() sub, however me.text is always returning "", meaning my logic fails.
Public Class Class1
Inherits Windows.Forms.TextBox
Public Sub New()
If Me.Text = "Something" Then
MessageBox.Show("Do something")
End If
End Sub
End Class
Any advice on how to overcome this hurdle?
Thanks in advance.
Cont....
Ok, so I think some more context would be good here.
This is something I wanted to try, to ease myself back into OOP, as I thought (!) it would be an easy starting point.
Im sure there is a class that I could download that would do everything I need, but I want to learn, not just copy/pase code from wherever I find.
So, the objective is to have a textbox which will also offer a "Caption" property. This property will contain text that is displayed in the textbox until it is clicked, ie "Your Name", and you click to then enter your name (basic stuff).
The original code posted was trying to demonstrate the issue I was having with obtaining the .Text property value in the New() method, as this is where I was trying to do some comparisons between .text and Caption. The code has now changed, and I no longer do this.
The main issue I am having at the moment is... when I add my control to a windows form, the textbox (.text) is empty, and I want it to be populated with the caption.
The code posted below is where I am after much trial and error. It's not too pretty, and theres some things that need to be thought about in more detail, but ultimately my current issue is getting the .text property populated with what I want and that being shown in the designer.
Public Class TextBoxWithCaption
Inherits Windows.Forms.TextBox
Dim Caption_Text As String = "Caption" ' Define default caption property value
Dim Caption_TextForeColor As Color = SystemColors.ControlDarkDark
Dim NoCaption_TextForeColor As Color = SystemColors.WindowText
Public Sub New()
MyBase.New()
Me.Text = Caption
Me.Width = 150
Me.ForeColor = Caption_TextForeColor
End Sub
Property Caption() As String
Get
Return Caption_Text
End Get
Set(value As String)
' Caption has been changed.
'
If Me.Text = Caption_Text Or String.IsNullOrEmpty(Me.Text) Then
' Caption property has changed, textbox has no user defined value, update the textbox with the new caption
Me.Text = value
End If
Caption_Text = value
End Set
End Property
Private Sub TextBoxWithCaption_GotFocus(sender As Object, e As EventArgs) Handles Me.GotFocus
If Me.Text = Caption Then
' If the caption is displayed, then clear it ready for the user to type
Me.Text = ""
Me.ForeColor = NoCaption_TextForeColor
End If
End Sub
Private Sub TextBoxWithCaption_LostFocus(sender As Object, e As EventArgs) Handles Me.LostFocus
If Me.Text = "" Then
' If the user has not typed anything, restore the caption
Me.Text = Caption
Me.ForeColor = Caption_TextForeColor
End If
End Sub
End Class
Upvotes: 0
Views: 318
Reputation: 19394
you can still do it and this is correct way because you want call constructor on underlying type
Public Sub New()
MyBase.New() '<-- this will init yout base text box and now you can use it
Me.Text = "Something"
End Sub
But if you had a tool like Resharper, it would warn you about "Virtual member call in constructor", which potentially can produce unexpected results with your property. You can read about online. To solve this issue add this property
Public Overrides NotOverridable Property Text As String
Get
Return MyBase.Text
End Get
Set (value as string)
MyBase.Text = value
End Set
End Property
Upvotes: 1
Reputation: 18320
The initial value of the Text
property will always be an empty string.
When changing a property through the designer the constructor will always be called prior to changing the property. This is because the control must be created before you can modify it. Modifying the Text
property of a Class1
variable that has not been initialized will throw a NullReferenceException.
If you look in your form's .Designer.vb
file in the InitializeComponent()
method, it would look something like this:
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container()
Me.Class11 = New YourNamespace.Class1()
Me.SuspendLayout()
'
'Class11
'
Me.Class11.Text = "Something"
...
End Sub
So in short: What you're doing is not possible unless you pass a value immediatelly to the constructor.
Upvotes: 1