Reputation: 49
So, basically, I'm programming this virtual keyboard, and I have to write code individually for each key, which are Buttons.
This is ridiculously tedious and I was wondering if there was maybe one single statement that could find the text of the key (Button
) pressed.
My current code is like this:
textbox.TextBox1.Text = textbox.TextBox1.Text + zh.Text
zh
is the name of a Button
, for context.
Now, I have to copy and paste this string of code over and over in each Button's Click
event.
I would think that there is a way to have the code grab the text of whatever Button
I press, then send that text to the TextBox
.
If this is indeed possible, would anyone know how to do it?
Upvotes: 1
Views: 1070
Reputation: 32223
Method 1:
Using the Designer, assign a single Click event to all your Buttons, then use the sender
object, casting it to Button or Control:
Private Sub MyKeys_Click(sender As Object, e As EventArgs) Handles MyKeysA.Click, MyKeysB.Click, (...)
TextBox1.AppendText(CType(sender, Button).Text)
End Sub
But the final event handler will have a lot of Buttons references attached to it. Not a beauty.
Method 2:
Create an event handler in code and assign it to all of your Buttons, using a classic delegate, with
AddHandler [Event], AddressOf [HandlerMethodName]
Assume that your Buttons have a common partial name, here "btnKey"
.
You could also use the Tag property and assign it a specific value(s) for your Keys Buttons.
You would then write in Where()
: b.Tag.ToString().Contains("[Some Common Identifier]")
.
Note that the
Tag
property value is of typeObject
, soContains()
is just a generic example. It could evaluate to an Integer type or anything else.
Note 1: To assign a common identifier to all the Keys Buttons, you can use the Form Designer: select all the Buttons and use the Properties Window to change the Tag
property of all the selected Buttons.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each btn As Button In Me.Controls.OfType(Of Button).Where(Function(b) b.Name.Contains("btnKey"))
AddHandler btn.Click, AddressOf Me.MyKeys_Click
Next
End Sub
Private Sub MyKeys_Click(sender As Object, e As EventArgs)
TextBox1.AppendText(DirectCast(sender, Control).Text)
End Sub
Note 2:
As Andrew Morton suggested in the comments, here the cast is performed using the DirectCast() operator. Since sender
is a Button and also Button derives from Control, you can use the light-weight DirectCast()
to see sender
as a Button or as a Control (since Button derives from Control and the Text
property is inherited from Control) and access its Text
property.
From the Docs:
[DirectCast()
] (...) it can provide somewhat better performance than CType when converting to and from data type Object.
I'm leaving CType() in the first example as a visual aide.
Difference between DirectCast() and CType() in VB.NET
Method 3:
Create an event handler in code and assign it to all of your Buttons using a Lambda as a method delegate:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each btn As Button In Me.Controls.OfType(Of Button).Where(Function(b) b.Name.Contains("btnKey"))
AddHandler btn.Click, Sub() TextBox1.AppendText(btn.Text)
Next
End Sub
Upvotes: 3