【问题标题】:How to find the text of a clicked Button in one single statement?如何在单个语句中找到单击按钮的文本?
【发布时间】:2019-04-13 22:17:04
【问题描述】:

所以,基本上,我正在编写这个虚拟键盘,我必须为每个键单独编写代码,它们是按钮。
这非常乏味,我想知道是否有一个语句可以找到按下的键 (Button) 的文本。

我目前的代码是这样的:

textbox.TextBox1.Text = textbox.TextBox1.Text + zh.Text

zhButton 的名称,用于上下文。

现在,我必须在每个 Button 的 Click 事件中一遍又一遍地复制并粘贴这段代码。
我认为有一种方法可以让代码抓取我按下的任何Button 的文本,然后将该文本发送到TextBox

如果这确实可行,有人知道该怎么做吗?

【问题讨论】:

    标签: vb.net winforms


    【解决方案1】:

    方法一
    使用设计器,将单个 Click 事件分配给所有 Button,然后使用 sender 对象,将其转换为 Button 或 Control:

    Private Sub MyKeys_Click(sender As Object, e As EventArgs) Handles MyKeysA.Click, MyKeysB.Click, (...)
        TextBox1.AppendText(CType(sender, Button).Text)
    End Sub
    

    但是最终的事件处理程序会附加很多 Buttons 引用。不是美女。

    方法二
    在代码中创建一个事件处理程序并将其分配给您的所有按钮,使用 classic 委托,
    AddHandler [Event], AddressOf [HandlerMethodName]

    假设您的 Button 有一个共同的部分名称,此处为 "btnKey"
    您还可以使用 Tag 属性并为您的按键按钮分配一个特定值。
    然后你会写Where()b.Tag.ToString().Contains("[Some Common Identifier]")

    注意Tag 属性值是Object 类型,所以 Contains() 只是一个通用示例。它可以评估为 整数类型或其他任何类型。

    注意 1: 要为所有 Keys Buttons 分配一个公共标识符,您可以使用表单设计器:选择所有 Buttons 并使用 Properties Window 更改所有 Keys Buttons 的 Tag 属性选定的按钮。

    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
    

    注2
    正如 Andrew Morton 在 cmets 中建议的那样,这里的演员表是使用 DirectCast() 运算符执行的。由于sender Button 并且Button 派生自Control,您可以使用轻量级 DirectCast()查看 sender作为 Button 或 Control(因为 Button 派生自 Control,Text 属性继承自 Control)并访问其 Text 属性。

    来自文档:
    [DirectCast()] (...) 它可以提供比 CType 更好的性能 在数据类型 Object 之间转换时。

    我将在第一个示例中留下CType() 作为视觉助手。

    Difference between DirectCast() and CType() in VB.NET

    方法3
    在代码中创建一个事件处理程序,并使用 Lambda 作为方法委托将其分配给您的所有按钮:

    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
    

    【讨论】:

    • 您不妨使用 DirectCast 而不是 CType,因为您已经知道它们是按钮。进一步阅读:Difference between DirectCast() and CType() in VB.NET.
    • @Andrew Morton 嗯,是的,值得一提,因为它可以在此处同时投射到 Button 和 Control。我会链接链接:)
    • @Jimi textbox.TextBox1 中的文本框在所有三种方法中都使用了什么?
    • @Mary 我不确定。你应该问OP,它在问题的代码sn-p中。也许,它只是表单容器名称(它是文本编辑器表单吗?),或另一个容器控件。我只是遵循现有模式。但这可能不是一个好主意,在更通用的用例场景中(也因为显然会产生问题那是为了什么?)。我正在删除它。
    • @Jimi 谢谢,我正在将它粘贴到我的代码库中并且想知道。
    猜你喜欢
    • 2022-07-30
    • 2015-11-01
    • 2016-02-21
    • 1970-01-01
    • 2021-07-20
    • 2017-09-29
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多