4

表单示例

我制作了一个自定义数字键盘控件,我想将它放在我的 winform 应用程序中。所有按钮都有一个OnClick事件,可以将值发送到我放置自定义控件的表单中的焦点文本框。像这样:

private void btnNum1_Click(object sender, EventArgs e)
{
    if (focusedCtrl != null && focusedCtrl is TextBox)
    {
        focusedCtrl.Focus();
        SendKeys.Send("1");
    }
}

focusedCtrl应该MouseDown在按钮的事件上设置,如下所示:

private void btnNum1_MouseDown(object sender, EventArgs e)
{
    focusedCtrl = this.ActiveControl;
}

其中this.ActiveControl表示窗体上的活动控件。

我的问题是按钮总是在事件检测到以前的焦点控件之前获得焦点。如何在按钮获得焦点之前检测哪个控件获得焦点?我应该使用另一个事件吗?提前致谢!

编辑:另外,我宁愿不使用GotFocus表单中每个文本框上的事件来设置focusedCtrl,因为这可能很乏味,因为我希望我的自定义控件的所有编码都在控件本身中,而不是在它所在的表单上被放置。(不过,如果没有其他实用的方法可以满足我的要求,我会这样做)

4

4 回答 4

3

您的要求是相当不明智的,您需要某种保证,以确保您的按钮不会将文本插入不适当的位置。你真的需要让表格合作,只有它知道什么地方是合适的。

但这并非不可能,您可以在输入事件被分派到具有焦点的控件之前对其进行嗅探。换句话说,记录在触发聚焦事件之前哪个控件具有焦点。这在带有 IMessageFilter 接口的 Winforms 中是可能的。

向您的项目添加一个新类并粘贴如下所示的代码。编译。将新控件从工具箱顶部拖放到表单上,替换现有按钮。

using System;
using System.Windows.Forms;

class CalculatorButton : Button, IMessageFilter {
    public string Digit { get; set; }

    protected override void OnClick(EventArgs e) {
        var box = lastFocused as TextBoxBase;
        if (box != null) {
            box.AppendText(this.Digit);
            box.SelectionStart = box.Text.Length;
            box.Focus();
        }
        base.OnClick(e);
    }
    protected override void OnHandleCreated(EventArgs e) {
        if (!this.DesignMode) Application.AddMessageFilter(this);
        base.OnHandleCreated(e);
    }
    protected override void OnHandleDestroyed(EventArgs e) {
        Application.RemoveMessageFilter(this);
        base.OnHandleDestroyed(e);
    }

    bool IMessageFilter.PreFilterMessage(ref Message m) {
        var focused = this.FindForm().ActiveControl;
        if (focused != null && focused.GetType() != this.GetType()) lastFocused = focused;
        return false;
    }
    private Control lastFocused;
}
于 2013-08-26T14:00:52.447 回答
2
Control focusedCtrl;
//Enter event handler for all your TextBoxes
private void TextBoxesEnter(object sender, EventArgs e){
    focusedCtrl = sender as TextBox;
}
//Click event handler for your btnNum1
private void btnNum1_Click(object sender, EventArgs e)
{
  if (focusedCtrl != null){
    focusedCtrl.Focus();
    SendKeys.Send("1");
  }
}
于 2013-08-26T13:32:02.830 回答
2

你有一个名为 lostFocus 的事件,你可以使用

button1.LostFocus +=new EventHandler(dataGridView1_LostFocus);

在事件中:

   Control lastFocused;

  void dataGridView1_LostFocus(object sender, EventArgs e)
  {
     lastFocused = sender as Control;
  }

这样你总能知道之前关注的 Control 是什么

现在,如果我错了,请纠正我,但你这样做是SendKeys.Send("1");为了知道哪个textBox需要接收号码。为此,您可以使用GotFocusevent 并仅将textBoxs 注册到它。

你也可以做windows正在做的事情,只使用一个文本框,如下所示: 在此处输入图像描述

如果它符合您的需求

于 2013-08-26T13:32:16.453 回答
0

将其与参数 forward = false 一起使用怎么样?

Control.SelectNextControl 方法

您可能会在“自定义数字键盘控件”上调用它。

于 2013-08-26T13:58:56.110 回答