You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断哪个CustomTextBox将焦点传递给CustomDataGridView

解决方案:获取焦点来源的CustomTextBox

要在betterdatagridview的OnEnter事件中判断焦点来自哪个CustomTextBox,由于你使用SendKeys模拟Tab切换焦点,系统不会自动传递来源控件信息,需要手动实现传递逻辑。以下是两种可靠的实现方式:

方式一:通过自定义事件传递来源控件

步骤1:扩展CustomTextBox,添加焦点离开事件

修改CustomTextBox代码,新增自定义事件来通知目标控件焦点来源:

// 自定义事件参数,传递来源TextBox和切换方向
public class CustomTextBoxFocusArgs : EventArgs
{
    public CustomTextBox Source { get; }
    public bool IsForwardTab { get; }

    public CustomTextBoxFocusArgs(CustomTextBox source, bool isForwardTab)
    {
        Source = source;
        IsForwardTab = isForwardTab;
    }
}

public partial class CustomTextBox : TextBox
{
    // 定义焦点离开事件
    public event EventHandler<CustomTextBoxFocusArgs>? FocusLeaving;

    protected override void OnKeyDown(KeyEventArgs e)
    {
        if (!DisableFeatures)
        {
            bool handled = false;
            bool isForward = false;

            if ((e.KeyCode == Keys.Enter || e.KeyCode == Keys.Down) && !string.IsNullOrEmpty(Text))
            {
                isForward = true;
                handled = true;
                e.Handled = true;
                e.SuppressKeyPress = true;
                TriggerEvent?.Invoke(Last, Name);
            }
            else if ((e.KeyCode == Keys.Back || e.KeyCode == Keys.Up) && Text.Length == 0)
            {
                isForward = false;
                handled = true;
                e.Handled = true;
                e.SuppressKeyPress = true;
            }

            if (handled)
            {
                // 触发事件,传递来源信息
                FocusLeaving?.Invoke(this, new CustomTextBoxFocusArgs(this, isForward));
                
                // 执行焦点切换
                if (isForward && !Last)
                    SendKeys.Send("{TAB}");
                else if (!isForward)
                    SendKeys.Send("+{TAB}");
                return;
            }
        }
        base.OnKeyDown(e);
    }
}

步骤2:修改betterdatagridview,记录来源控件并判断

在betterdatagridview中添加字段存储来源控件,在OnEnter中根据来源设置单元格:

public partial class betterdatagridview : DataGridView
{
    private CustomTextBox? _focusSource;

    // 对外提供设置来源的方法
    public void SetFocusSource(CustomTextBox source)
    {
        _focusSource = source;
    }

    protected override void OnEnter(EventArgs e)
    {
        if (RowCount > 0)
        {
            if (_focusSource != null)
            {
                // 根据来源TextBox的名称或自定义标识判断
                if (_focusSource.Name == "txtFromTop") // 替换为你的TextBox名称
                {
                    CurrentCell = Rows[0].Cells[0];
                }
                else if (_focusSource.Name == "txtFromBottom")
                {
                    CurrentCell = Rows[RowCount - 1].Cells[0];
                }
                // 清空记录,避免下次误判
                _focusSource = null;
            }

            BeginEdit(true);
            if (EditingControl is TextBox textBox)
            {
                textBox.SelectionStart = textBox.Text.Length;
            }
        }
        base.OnEnter(e);
    }
}

步骤3:在宿主窗体中绑定事件

打开你的窗体代码,为每个CustomTextBox绑定FocusLeaving事件,将来源信息传递给DataGridView:

public partial class YourMainForm : Form
{
    public YourMainForm()
    {
        InitializeComponent();
        // 绑定事件
        txtFromTop.FocusLeaving += TextBox_FocusLeaving;
        txtFromBottom.FocusLeaving += TextBox_FocusLeaving;
    }

    private void TextBox_FocusLeaving(object? sender, CustomTextBoxFocusArgs e)
    {
        // 判断切换方向是否会到DataGridView(可选,根据你的控件顺序调整)
        if (e.IsForwardTab || !e.IsForwardTab)
        {
            yourDataGridView.SetFocusSource(e.Source);
        }
    }
}

方式二:直接获取前一个焦点控件(简单但需注意兼容性)

如果你的项目使用.NET Framework 4.8或更高版本,可以尝试直接使用PreviousFocusedControl属性获取前一个焦点控件:

protected override void OnEnter(EventArgs e)
{
    if (RowCount > 0)
    {
        // 获取前一个焦点控件
        var previousControl = FindForm()?.ActiveControl?.PreviousFocusedControl;
        if (previousControl is CustomTextBox sourceTxt)
        {
            if (sourceTxt.Name == "txtFromTop")
            {
                CurrentCell = Rows[0].Cells[0];
            }
            else if (sourceTxt.Name == "txtFromBottom")
            {
                CurrentCell = Rows[RowCount - 1].Cells[0];
            }
        }

        BeginEdit(true);
        if (EditingControl is TextBox textBox)
        {
            textBox.SelectionStart = textBox.Text.Length;
        }
    }
    base.OnEnter(e);
}

注意:PreviousFocusedControl依赖系统焦点记录,在SendKeys模拟切换的场景下可能存在异步延迟,导致获取不到正确的来源控件,因此方式一更稳定可靠。

内容的提问来源于stack exchange,提问作者Nisha Goel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:33:16