如何判断哪个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
相关产品推荐
相关产品推荐

