w60
w60

Reputation: 49

How to find the text of a clicked Button in one single statement?

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

Answers (1)

Jimi
Jimi

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 type Object, so Contains() 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.

  • Here, assuming all Controls are child of the Form. Specify the actual Parent if's a different Container

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

Related Questions