简体   繁体   English

在TabControl中选择标签页而不会窃取焦点

[英]Select Tab Page in TabControl without stealing focus

Using TabControl.SelectTab("...") shows the tab but it also gives the tab focus. 使用TabControl.SelectTab("...")显示选项卡,但它也提供选项卡焦点。 I would like to show a particular tab, but keep focus where it is. 我想展示一个特定的标签,但要保持焦点。

I have data rows in a grid. 我在网格中有数据行。 Based on properties of the selected row, I show a different tab page to have a different UI layout. 根据所选行的属性,我显示了一个不同的标签页,以具有不同的UI布局。 But when using arrow keys to scroll through rows, the focus switches to the selected tab -- which I don't want to happen. 但是当使用箭头键滚动行时,焦点会切换到选定的选项卡 - 我不想发生这种情况。

Thanks. 谢谢。

You can try disabling the TabControl before setting the selected tab, then re-enabling it. 您可以尝试在设置所选选项卡之前禁用TabControl ,然后重新启用它。 This will prevent it from taking focus. 这将防止它成为焦点。 I tested this on a tab control with a few controls on it, and didn't see any visual change, but you'll have to try it in your UI and see whether it's ok for you. 我在一个带有几个控件的选项卡控件上对此进行了测试,并没有看到任何视觉上的变化,但您必须在UI中尝试它并查看它是否适合您。

tabControl1.Enabled = false;
tabControl1.SelectTab("tabPage4");
tabControl1.Enabled = true;

To be safe, you could put the line to re-enable the TabControl in a finally block to make sure it doesn't get left disabled. 为了安全起见,您可以将该行重新启用finally块中的TabControl,以确保它不会被禁用。

I don't think there's a built-in function, but you can do in this way: 我认为没有内置函数,但您可以这样做:

private bool skipSelectionChanged = false;

private void dataGridView_SelectionChanged(object sender, EventArgs e)
{
    if (skipSelectionChanged)
        return;

    // supposing we decide tab[0] has to be selected...
    this.SelectTabWithoutFocus(this.tabControl1.TabPages[0]);
}

private void SelectTabWithoutFocus(TabPage tabPage)
{
    this.skipSelectionChanged = true;

    // "this" is the form in my case, so you get the current focused control
    // (ActiveControl), backup it, and re-set it after Tab activation

    var prevFocusedControl = this.ActiveControl;
    if (this.ActiveControl != null)
    {
        this.tabControl1.SelectedTab = tabPage;
        prevFocusedControl.Focus();
    }
    this.skipSelectionChanged = false;
}

Here, I backup the current focused control, select the desired tab, and finally set the focus to the original control. 在这里,我备份当前的聚焦控件,选择所需的选项卡,最后将焦点设置为原始控件。

Skipping boolean is necessary, because giving the focus to the grid you trigger SelectionChanged event again, causing infinite looping. 跳过布尔值是必要的,因为将焦点给予网格会再次触发SelectionChanged事件,从而导致无限循环。

This selects the tab pages while keeping the focus on top, as asked here above: 这会选择标签页,同时将焦点保持在顶部,如上所述:

            tc.TabPages[0].Enabled = false;
            tc.SelectTab(0);
            tc.TabPages[0].Enabled = true;

tc is here my instance for the TabControl type (ie it IS my tab control, and it has a few "tab pages"). tc在这里是TabControl类型的实例(即它是我的选项卡控件,它有一些“标签页”)。 This works properly for me. 这适合我。 My purpose is to loop through these tab pages with the Left and Right keys (arrows) ie when I go forwards (by Key.Right ) and reach the last tabpage I want to have my focus on [0] without activating the DataGridView which I have in that page, and when I go backwards (by Key.Left ) and reach [0] I want to have [tc.TabCount - 1] enabled, which is the last one. 我的目的是使用向左和向右键(arrows)循环浏览这些标签页,即当我前进(通过Key.Right )并到达最后一个tabpage我希望将焦点放在[0]而不激活DataGridView我在那个页面中,当我向后(通过Key.Left )并到达[0]我希望启用[tc.TabCount - 1] ,这是最后一个。 The code for this case is: 这种情况的代码是:

            tc.TabPages[tc.TabCount - 1].Enabled = false;
            tc.SelectTab(tc.TabCount - 1);
            tc.TabPages[tc.TabCount - 1].Enabled = true;

The complete piece of code is: 完整的代码是:

    private bool KeyTc(System.Windows.Forms.Keys keyData)
    {
        if (keyData == K.Left && tc.SelectedIndex == 0)
        {
            tc.TabPages[tc.TabCount - 1].Enabled = false;
            tc.SelectTab(tc.TabCount - 1);
            tc.TabPages[tc.TabCount - 1].Enabled = true;
            return true;
        }
        else if (keyData == K.Right && tc.SelectedIndex == tc.TabCount - 1)
        {
            tc.TabPages[0].Enabled = false;
            tc.SelectTab(0);
            tc.TabPages[0].Enabled = true;
            return true;
        }
        return false;
    }

This bool KeyTc is returned to a case in a switch statement for key evaluation in: 这个bool KeyTc返回到switch语句中的一个案例,用于以下方面的密钥评估:

protected override bool ProcessCmdKey(ref Message keyMsg, Keys keyData)
    { switch keyData { ... } }

Base on the solution proposed by "Jeff Ogata : You can try disabling the TabControl before setting the selected tab, then re-enabling it. This will prevent it from taking focus", here bellow my solution: 基于“Jeff Ogata提出的解决方案:您可以尝试在设置选定的选项卡之前禁用TabControl,然后重新启用它。这将阻止它获得焦点”,这是我的解决方案:

tabMain.SelectedPageChanging += (s, e) =>
        { 
            tabMain.Enabled = false;
        };

        tabMain.SelectedPageChanged += (s, e) =>
        {
            tabMain.Enabled = true;                
        };

Note: this code is using DevExpress "DevExpress.XtraTab.XtraTabControl". 注意:此代码使用DevExpress“DevExpress.XtraTab.XtraTabControl”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM