我有一个TabControl,并以编程的方式将Tabpages添加到其中。每个TabPage在其中加载一个UserControl,每个用户控件包含几个控件。例如:
TabPage1
UserControl1
TextBox1, TextBox2, TextBox3
TabPage2
UserControl2
TextBox4, TextBox5, TextBox6
现在,我希望每当用户更改该选项卡时,当再次选择该选项卡时,该选项卡的先前重点控件再次获得焦点。
示例:
怎么办?
发布于 2022-05-05 13:15:50
可能的解决办法:
在窗体中重写UpdateDefaultButton();每当控件成为ActiveControl
时都调用此方法。
当然,如果UserControls在TabPages中,那么ActiveControl就是UserControl,但是您需要它的子控件,该子控件是当前关注的焦点。
在示例代码中,我使用GetFocus()函数获取焦点控件的句柄,然后使用Control.FromHandle()获取带有该句柄的控制实例,如果不是null
,则将这些信息与当前的TabPage一起存储在字典中。
当引发TabControl的已选择事件时,检查字典是否存储了新的当前TabPage,如果控件与该TabPage相关联,则将焦点移动到它上。
(我使用BeginInvoke()
是因为我们正在更改Selected
处理程序中的ActiveControl,这反过来会导致对UpdateDefaultButton()
的调用)
Private tabPagesActiveControl As New Dictionary(Of Integer, Control)
Protected Overrides Sub UpdateDefaultButton()
MyBase.UpdateDefaultButton()
If ActiveControl Is Nothing Then Return
If TypeOf ActiveControl.Parent Is TabPage Then
Dim tp = DirectCast(ActiveControl.Parent, TabPage)
Dim tabPageIdx = DirectCast(tp.Parent, TabControl).SelectedIndex
Dim ctl = FromHandle(GetFocus())
If ctl IsNot Nothing Then
If tabPagesActiveControl.Count > 0 AndAlso tabPagesActiveControl.ContainsKey(tabPageIdx) Then
tabPagesActiveControl(tabPageIdx) = ctl
Else
tabPagesActiveControl.Add(tabPageIdx, ctl)
End If
End If
End If
End Sub
Private Sub TabControl1_Selected(sender As Object, e As TabControlEventArgs) Handles TabControl1.Selected
Dim ctl As Control = Nothing
If tabPagesActiveControl.TryGetValue(e.TabPageIndex, ctl) Then
BeginInvoke(New Action(Sub() ctl.Focus()))
End If
End Sub
Win32函数声明:
<DllImport("user32.dll", CharSet:=CharSet.Auto)>
Friend Shared Function GetFocus() As IntPtr
End Function
C#版本
private Dictionary<int, Control> tabPagesActiveControl = new Dictionary<int, Control>();
protected override void UpdateDefaultButton()
{
base.UpdateDefaultButton();
if (ActiveControl is null) return;
if (ActiveControl.Parent is TabPage tp) {
var tabPageIdx = (tp.Parent as TabControl).SelectedIndex;
var ctl = FromHandle(GetFocus());
if (ctl != null) {
if (tabPagesActiveControl.Count > 0 && tabPagesActiveControl.ContainsKey(tabPageIdx)) {
tabPagesActiveControl[tabPageIdx] = ctl;
}
else {
tabPagesActiveControl.Add(tabPageIdx, ctl);
}
}
}
}
private void tabControl1_Selected(object sender, TabControlEventArgs e)
{
if (tabPagesActiveControl.TryGetValue(e.TabPageIndex, out Control ctl)) {
BeginInvoke(new Action(() => ctl.Focus()));
}
}
Win32函数声明:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern IntPtr GetFocus();
这就是它的工作原理:
注意:TabPage2
和TabPage3
包含带有2 TextBoxes和ListBox的UserControl实例。TabPage1
包含一个TextBox和一个NumericUpDown。
https://stackoverflow.com/questions/72122719
复制相似问题