如何创建一个可以将键发送到控件而不会失去焦点的按钮 - 虚拟键盘

Posted

技术标签:

【中文标题】如何创建一个可以将键发送到控件而不会失去焦点的按钮 - 虚拟键盘【英文标题】:How to create a Button that can send keys to a conrol without losing focus - Virtual Keyboard 【发布时间】:2018-05-31 14:42:39 【问题描述】:

如何制作一个可以将键发送到 datagridview 的按钮(因此我需要在 datagridview 失去焦点之前以某种方式将其返回到其状态)

我会解释问题

我有一个带有 datagridview 和一些按钮的表单

我可以点击按钮,它会输入相应的字母,

dataGridView1.Focus();
SendKeys.Send("a");  //or m or z, depending on the text of the button.

该按钮用于将数据输入到 datagridview 中。我可以让它只有在调用 datagridview 的 enter 方法时才启用。单击按钮时,datagridview 会失去焦点,因此在发送密钥之前,我必须再次赋予它焦点。因此上面的两行。

我希望用户能够使用按钮将数据输入数据网格。

问题是,假设我希望用户能够输入文本“maz”,但我做不到。我只得到一个单独的 a 或 m 或 z。即使我可以将单元格重新置于可编辑模式,我也需要记住光标的位置。所以如果有人在单元格中输入 asdf 并将光标放在 d 和 f 之间,然后单击 m,我想要它说 asdmf。

我不知道该怎么做。

我有一个想法.. 如果有一种方法可以注册鼠标悬停在按钮上并且单击被按下,但又不会失去对 datagridview 的关注,那么这将是一种可以完成的方法。不过我不知道该怎么做,而且我对不同的方式感兴趣。

【问题讨论】:

是否有理由必须使用 sendkeys 而不是修改单元格(或底层绑定对象)的内容? 我想它可以修改单元格的内容,但仍然存在单击按钮会导致失去焦点从而失去光标位置的问题,所以如果我想让 asdf 成为 asdmf 我不看看如何。 【参考方案1】:

不可选择的按钮来像虚拟键盘一样发送按键

制作一个不可选择的按钮然后处理它的点击事件和发送键就足够了。这样,这些按钮可以像虚拟键盘键一样工作,并且焦点将保持在具有焦点的控件上,同时将键发送到焦点控件。

public class ExButton:Button

    public ExButton()
    
        SetStyle(ControlStyles.Selectable, false);
    

然后处理点击事件并发送密钥:

private void exButton1_Click(object sender, EventArgs e)

    SendKeys.SendWait("A");


控件的 SetStyle 扩展方法

有什么方法可以在不使用 Control 的情况下调用 SetStyle 继承?

是的,使用Reflection,有。创建这个扩展方法:

public static class Extensions

    public static void SetStyle(this Control control, ControlStyles flags, bool value)
    
        Type type = control.GetType();
        BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
        MethodInfo method = type.GetMethod("SetStyle", bindingFlags);
        if (method != null)
        
            object[] param =  flags, value ;
            method.Invoke(control, param);
        
    

然后以这种方式使用它,在您的表单Load 事件中:

this.button1.SetStyle(ControlStyles.Selectable, false);

那么 button1 在没有继承的情况下将是不可选择的。

【讨论】:

有什么方法可以在不使用继承的情况下在按钮上执行SetStyle(ControlStyles.Selectable, false); 使其不可选择? @barlop 是的,有。我编辑了帖子以使答案对您有用。 顺便说一句,因为我找不到重复的问题 是否有任何方法可以在不使用继承的情况下在控件上调用 SetStyle?,我认为最好问它是一个新问题,我将在那里发布编辑。这样,这个问题对未来的读者会更有用。 使用反射的代码同样可以工作,无需将其放入扩展方法中。可能同时介绍这两个概念有点过分! @barlop 删除 this 以便 SetStyle 将 Control 作为常规参数。然后,如果您将 SetStyle 放在名为 Misc 的类中,您将调用 Misc.SetStyle(button1, ControlStyles.Selectable, false)

以上是关于如何创建一个可以将键发送到控件而不会失去焦点的按钮 - 虚拟键盘的主要内容,如果未能解决你的问题,请参考以下文章

C# Winform 控件或窗体失去焦点时,获取键盘输入数据(我用winform获取另一个窗口的数据)

C++ Builder中如何让窗体一直显示最前,焦点不失去,就是点不了别的窗体,切换不了窗体,总处在被激活状态

Winform中Treeview控件失去焦点,如何将选择的节点还设置为高亮显示?

WPF虚拟键盘如何不获得当前焦点

由于文本框失去焦点,按钮需要单击两次

MFC 中关于Edit控件问题