微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

TabPage 选择,当重新选择一个 TabPage 时,将焦点移动到上一个 ActiveControl

如何解决TabPage 选择,当重新选择一个 TabPage 时,将焦点移动到上一个 ActiveControl

当重新访问 TabPage 时,我需要一些帮助来聚焦特定控件。我关注了许多其他博客,但我自己无法解决问题。

我在 MDIForm 中创建了 TabPages:

Public Sub Tab_Open(Of T As {Form,New})(name As String,NameofTab As String,Tabnumber As String)

    Dim _formByName As New Dictionary(Of String,Form)
    Dim Frm As Form = nothing

    If Not _formByName.TryGetValue(name,Frm) OrElse _formByName(name).Isdisposed Then
        Frm = New T()
        _formByName(name) = Frm
    End If

    Dim childTab As TabPage = New TabPage With {
        .Name = NameofTab & " : " & Tabnumber,.Text = NameofTab & " : " & Tabnumber,.Tag = Frm.Name
    }

    Form1.tabForms.TabPages.Add(childTab)

    Frm.TopLevel = False
    Frm.FormBorderStyle = FormBorderStyle.None
    Frm.Parent = Form1.tabForms.TabPages(Form1.tabForms.TabCount - 1)
    Frm.Dock = DockStyle.Fill
    Frm.Show()
   
    Form1.tabForms.SelectedTab = childTab
    Form1.tabForms.Visible = True
End Sub

假设在第一个 TabPage 中,焦点位于一个 TextBox(带有 TabIndex = 4)上,现在我可以点击第二个 TabPage。
经过一些计算,当我选择上一个 TabPage 时,焦点应该再次设置为带有 TabIndex = 4 的 TextBox,但没有发生这种情况。

我尝试在 MDIForm 中创建一个字典:

Public Tab_Last_Focus_info As New Dictionary(Of String,String())

SelectedindexChanged 我有这个代码

 Private Sub tabForms_SelectedindexChanged(sender As Object,e As EventArgs) Handles tabForms.SelectedindexChanged

    If Tab_Last_Focus_info.ContainsKey(tabForms.SelectedTab.Name) Then
        Dim FullTypeName1 As String = String.Format("{0}",Tab_Last_Focus_info.Item(tabForms.SelectedTab.Name))
        Dim Indxval As String = String.Format("{1}",Tab_Last_Focus_info.Item(tabForms.SelectedTab.Name))

        Dim FullTypeName As String = Application.ProductName & "." & FullTypeName1
        Dim FormInstanceType As Type = Type.GetType(FullTypeName,True,True)
        Dim frm As Form = CType(Activator.CreateInstance(FormInstanceType),Form)
        Dim Focus_on As Integer = Integer.Parse(Indxval)

        frm.Controls(Focus_on).Focus()
        ' Not working too =>
        ' frm.Controls(Focus_on).Select() 

        ' Invisible or disabled control cannot be activated =>
        ' ActiveControl = frm.Controls(Focus_on) 'System.ArgumentException: 
    End If
End Sub

在通过菜单打开的表单中,我有这个焦点控件的代码

Private Sub All_Got_Focus(sender As Object,e As EventArgs) Handles TB_ImageLoc.GotFocus,TB_CompWebsite.GotFocus,TB_CompPinCD.GotFocus,TB_CompPAN.GotFocus,TB_CompName.GotFocus,TB_CompMobile.GotFocus,TB_CompMD.GotFocus,TB_CompLL.GotFocus,TB_CompGSTIN.GotFocus,TB_CompFax.GotFocus,TB_CompEmail.GotFocus,TB_CompCD.GotFocus,TB_CompAreaCity.GotFocus,RTB_CompADD.GotFocus,PB_logo.GotFocus,DTP_Compest.GotFocus,DGV_CompList.GotFocus,CHKB_CompIsRegTrans.GotFocus,CB_CompStateID.GotFocus,CB_CompdistrictID.GotFocus,But_Upd.GotFocus,But_Selectlogo.GotFocus,But_Search.GotFocus,But_Reset.GotFocus,But_Refresh.GotFocus,But_GridSelect.GotFocus,But_Exit.GotFocus,But_Edit.GotFocus,But_Del.GotFocus,But_Add.GotFocus
   
    If Form1.Tab_Last_Focus_info.ContainsKey(Form1.tabForms.SelectedTab.Name) Then
        Form1.Tab_Last_Focus_info.Remove(Form1.tabForms.SelectedTab.Name)
    End If

    Form1.Tab_Last_Focus_info.Add(Form1.tabForms.SelectedTab.Name,New String() {Me.Name,Me.ActiveControl.TabIndex})
End Sub

现在在 TabIndexChange 中,我从字典中获得了正确的值,但我无法专注于所需的选项卡。

请帮助我,让我知道我遗漏了什么或需要注意这个问题,或者请让我知道任何其他更好的想法。

解决方法

第一件事,一个建议:在一个干净的项目中测试此代码,其中您有一个 MDIParent 和一个带有 TabControl 的表单,其中包含 2 个或多个 TabPage,包含不同类型的控件。测试功能,然后应用到打算使用它的项目。


你需要跟踪一个TabPage中选中的Control——当前的ActiveControl——切换到其他TabPages,当TabPage中的前一个ActiveControl被引入时恢复重新回到前面。

程序很简单,实现如下:

  • 要跟踪当前的 ActiveControl - 具有焦点的控件,您需要知道控件何时成为 ActiveControl。此控件当然必须是 TabPage 的子级。
    ContainerControl 类(从 Form 派生的类)有一个 protected virtual 方法 UpdateDefaultButton(),它在 Form 类中被覆盖。它用于确定当用户按下 Enter 键时激活哪个子 Button。
    每次新的 Control 成为 ActiveControl 时都会调用此方法:覆盖它,我们可以在发生这种情况时得到通知,因此我们可以检查新的 ActiveControl 是否是我们感兴趣的,因为它是我们的 TabControl 的 TabPage 的子级。

  • 当新的 ActiveControl 是我们需要跟踪的时候,我们可以将这个 Control 的引用和它所属的 TabPage 的索引存储在一个集合中,这样我们就可以使用这个参考,当所选的梆铃更改时,将其再次设置为其签收中的ActiveControl。

在这里,为了存储状态,我使用了 Dictionary(Of Integer,Control),其中 Key 是 TabPage 的索引,Value 是参考其 ActiveControl。

当引发 TabControl.Selected 事件时 - 在选择了 TabPage 之后 - 我们可以查找 Dictionary 并恢复该 TabPage 的先前 ActiveControl(如果已存储)。

► 这里,BeginInvoke() 用于推迟设置新 ActiveControl 的动作,因为这也会导致调用 UpdateDefaultButton() 并且在 TabControl.Selected 事件处理程序完成之前调用此方法.

Public Class SomeMdiChildForm

    Private tabPagesActiveControl As New Dictionary(Of Integer,Control)()

    ' This method is called each time a Control becomes the ActiveControl
    Protected Overrides Sub UpdateDefaultButton()
        MyBase.UpdateDefaultButton()

        If TypeOf ActiveControl.Parent Is TabPage Then
            Dim tabPageIdx = CType(CType(ActiveControl.Parent,TabPage).Parent,TabControl).SelectedIndex
            If tabPagesActiveControl.Count > 0 AndAlso tabPagesActiveControl.ContainsKey(tabPageIdx) Then
                tabPagesActiveControl(tabPageIdx) = ActiveControl
            Else
                tabPagesActiveControl.Add(tabPageIdx,ActiveControl)
            End If
        End If
    End Sub

    Private Sub TabControl1_Selected(sender As Object,e As TabControlEventArgs) Handles TabControl1.Selected
        Dim ctrl As Control = Nothing
        If tabPagesActiveControl.TryGetValue(e.TabPageIndex,ctrl) Then
            BeginInvoke(New Action(Sub() Me.ActiveControl = ctrl))
        End If
    End Sub
End Class

C# 版本
(假设 tabControl1 是 TabControl 实例的名称)

public partial class SomeForm : Form
{
    private Dictionary<int,Control> tabPagesActiveControl = new Dictionary<int,Control>();

    // [...]

    // This method is called each time a Control becomes the ActiveControl
    protected override void UpdateDefaultButton()
    {
        base.UpdateDefaultButton();
        if (ActiveControl.Parent is TabPage tp) {
            var tabPageIdx = (tp.Parent as TabControl).SelectedIndex;
            if (tabPagesActiveControl.Count > 0 && tabPagesActiveControl.ContainsKey(tabPageIdx)) {
                tabPagesActiveControl[tabPageIdx] = ActiveControl;
            }
            else {
                tabPagesActiveControl.Add(tabPageIdx,ActiveControl);
            }
        }
    }

    private void tabControl1_Selected(object sender,TabControlEventArgs e)
    {
        if (tabPagesActiveControl.TryGetValue(e.TabPageIndex,out Control ctrl)) {
            BeginInvoke(new Action(() => ActiveControl = ctrl));
        }
    }
}
,

如前所述,Tab_Open sub 用于创建表单作为选项卡。

在主窗体 (MDI) 中创建的字典为 Public tabPagesActiveControl As New Dictionary(Of String,Integer)

在每个表单中,当控件获得焦点时,值已添加到字典中

Private Sub DateTimePicker1_Leave(sender As Object,e As EventArgs) Handles RadioButton1.GotFocus,DateTimePicker1.GotFocus,ComboBox1.GotFocus,CheckBox1.GotFocus,Button1.GotFocus,TextBox3.GotFocus,TextBox4.GotFocus,RichTextBox1.GotFocus

        If Form1.tabPagesActiveControl.ContainsKey(Form1.TabControl1.SelectedTab.Name) Then
            Form1.tabPagesActiveControl(Form1.TabControl1.SelectedTab.Name) = Me.ActiveControl.TabIndex
        Else
            Form1.tabPagesActiveControl.Add(Form1.TabControl1.SelectedTab.Name,Me.ActiveControl.TabIndex)
        End If
        
    End Sub

当标签被聚焦时:

Private Sub TabControl1_SelectedIndexChanged(sender As Object,e As EventArgs) Handles TabControl1.SelectedIndexChanged

        If tabPagesActiveControl.ContainsKey(Me.TabControl1.SelectedTab.Name) Then
Dim Indxval As String = String.Format(tabPagesActiveControl.Item(Me.TabControl1.SelectedTab.Name))

            SendKeys.Send("{TAB " & Indxval & "}")

        End If

    End Sub

正如评论中提到的,它有缺陷。请检查并提供帮助或让我知道可以尝试什么。

,

我终于在挣扎了 8 天后解决了这个问题:)

正如我之前提到的,我使用问题中提到的 Sub Tab_Open 打开表单作为选项卡。

以 MDI 形式定义或创建新字典

Public tabPagesActiveControl As New Dictionary(Of String,Control)

并将控制变量定义为

Dim Sel_Control As Control

现在在每个表单中,当控件获得焦点时,我有以下代码将当前控件单独分配给字典:

Private Sub All_Focus(sender As Object,e As EventArgs) Handles TBox_Reg_website.GotFocus,TBox_Reg_To.GotFocus,TBox_Reg_State.GotFocus,TBox_Reg_PinCD.GotFocus,TBox_Reg_PAN.GotFocus,TBox_Reg_office_num.GotFocus,TBox_Reg_mobile_num.GotFocus,TBox_Reg_GSTIN.GotFocus,TBox_Reg_fax_no.GotFocus,TBox_Reg_email.GotFocus,TBox_Reg_country.GotFocus,TBox_Reg_Company.GotFocus,TBox_Reg_City.GotFocus,TBox_Reg_Add2.GotFocus,TBox_Reg_Add1.GotFocus,TB_Curr_website.GotFocus,TB_Curr_state.GotFocus,TB_Curr_RegTo.GotFocus,TB_Curr_Pincd.GotFocus,TB_Curr_Pan.GotFocus,TB_Curr_office_num.GotFocus,TB_Curr_Mobile_num.GotFocus,TB_Curr_Gstin.GotFocus,TB_Curr_fax_no.GotFocus,TB_Curr_email.GotFocus,TB_Curr_country.GotFocus,TB_Curr_Company.GotFocus,TB_Curr_city.GotFocus,TB_Curr_add2.GotFocus,TB_Curr_add1.GotFocus,PICBox_Reg_Logo.GotFocus,MSP_Reg.GotFocus,Label9.GotFocus,Label8.GotFocus,Label7.GotFocus,Label6.GotFocus,Label5.GotFocus,Label4.GotFocus,Label3.GotFocus,Label2.GotFocus,Label15.GotFocus,Label14.GotFocus,Label13.GotFocus,Label12.GotFocus,Label11.GotFocus,Label10.GotFocus,Label1.GotFocus,ChkBx_Upd_Logo.GotFocus,Chkbox_NoLogo.GotFocus

        If Form1.tabPagesActiveControl.ContainsKey(Form1.TabControl1.SelectedTab.Name) Then
            Form1.tabPagesActiveControl.Remove(Form1.TabControl1.SelectedTab.Name)
        End If

        Form1.tabPagesActiveControl.Add(Form1.TabControl1.SelectedTab.Name,Me.ActiveControl)

    End Sub

和在MDI形式时,当标签选择具有以下代码的索引变化时:

Private Sub TabControl1_SelectedIndexChanged(sender As Object,e As EventArgs) Handles TabControl1.SelectedIndexChanged

        If tabPagesActiveControl.ContainsKey(Me.TabControl1.SelectedTab.Name) Then
            
            Sel_Control = tabPagesActiveControl.Item(Me.TabControl1.SelectedTab.Name)
            
            Sel_Control.Focus()
            
        End If

    End Sub

谢谢:)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。