首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在选项卡之间切换时,将焦点恢复到TabPage以前集中的控件

如何在选项卡之间切换时,将焦点恢复到TabPage以前集中的控件
EN

Stack Overflow用户
提问于 2022-05-05 06:17:20
回答 1查看 98关注 0票数 2

我有一个TabControl,并以编程的方式将Tabpages添加到其中。每个TabPage在其中加载一个UserControl,每个用户控件包含几个控件。例如:

代码语言:javascript
运行
复制
TabPage1
   UserControl1
      TextBox1, TextBox2, TextBox3
TabPage2
   UserControl2
      TextBox4, TextBox5, TextBox6

现在,我希望每当用户更改该选项卡时,当再次选择该选项卡时,该选项卡的先前重点控件再次获得焦点。

示例:

  1. 比方说,重点放在TabPage1→UserControl1→TextBox2上
  2. 然后我点击TagPage 2→UserControl2→TextBox4
  3. 然后我再次点击TabPage1,我希望TextBox2获得焦点。

怎么办?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-05 13:15:50

可能的解决办法:

在窗体中重写UpdateDefaultButton();每当控件成为ActiveControl时都调用此方法。

当然,如果UserControls在TabPages中,那么ActiveControl就是UserControl,但是您需要它的子控件,该子控件是当前关注的焦点。

在示例代码中,我使用GetFocus()函数获取焦点控件的句柄,然后使用Control.FromHandle()获取带有该句柄的控制实例,如果不是null,则将这些信息与当前的TabPage一起存储在字典中。

当引发TabControl的已选择事件时,检查字典是否存储了新的当前TabPage,如果控件与该TabPage相关联,则将焦点移动到它上。

(我使用BeginInvoke()是因为我们正在更改Selected处理程序中的ActiveControl,这反过来会导致对UpdateDefaultButton()的调用)

  • 请注意,这里我没有验证焦点控件是否是与TabPage不同的容器的子容器:如果您的TabPages中有嵌套容器,则需要一个递归方法来检查其中一个祖先是否是TabPage。
代码语言:javascript
运行
复制
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函数声明:

代码语言:javascript
运行
复制
<DllImport("user32.dll", CharSet:=CharSet.Auto)>
Friend Shared Function GetFocus() As IntPtr
End Function

C#版本

代码语言:javascript
运行
复制
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函数声明:

代码语言:javascript
运行
复制
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern IntPtr GetFocus();

这就是它的工作原理:

注意:TabPage2TabPage3包含带有2 TextBoxes和ListBox的UserControl实例。TabPage1包含一个TextBox和一个NumericUpDown。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72122719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档