带有自定义 ToolStripControlHost 的 ToolStrip 使 Tab 键顺序焦点变得奇怪

Ada*_*her 3 c# winforms toolstripcontrolhost

我正在经历一些奇怪的行为。让我试着解释一下,我将代码精简到最低限度,但问题仍然存在。所以首先,我使用 VS2013 和 .NET 4.0,我使用的是 Windows 8.1。

所以我有一个自定义UserControlTextBox多数民众赞成正在通过使用ToolStripControlHost,如果我专注于这个文本框和命中TAB通过控制这个文本框的左侧,它只是个周期。如果我将它聚焦并点击SHIFT+ TAB,它会在它右侧的按钮之间循环。

在此处输入图片说明

所以这是我的表格的一个例子。中间的文本框是一个自定义控件。我的代码(尽可能简化)如下所示:

[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)]
public class ToolStripTestControl : ToolStripControlHost
{
    public ToolStripTestControl() : this(new TestControl()) { }
    public ToolStripTestControl(Control c) : base(c) { }
}

public class TestControl : UserControl
{
    private TextBox _textBox = new TextBox();

    public TestControl()
    {
        _textBox.Dock = DockStyle.Fill;
        this.Controls.Add(_textBox);
    }

    protected override Size DefaultMinimumSize { get { return new Size(100, 22); } }
}
Run Code Online (Sandbox Code Playgroud)

只需创建一个新的 WinForms (.NET4) 项目并按照以下步骤操作即可复制问题:

  1. 添加新的类文件并粘贴上面的代码。
  2. 建造
  3. 将 ToolStrip 添加到您的表单
  4. 在 ToolStrip 上添加一个 Button、我的自定义控件和另一个 Button(通过设计器是我一直在做的)

一旦运行...

  1. 专注于自定义控件
  2. 点击TAB几次,它应该只关注左边的控件。
  3. 点击SHIFT+TAB几次,它只会向右聚焦。

有谁知道问题是什么 - 或者我如何解决这个问题?我整天都在扯头发试图解决这个问题。我终于剥离了我的代码,但我似乎无法让它工作。我什至尝试覆盖大部分OnEnter/OnGotFocus功能并自己完成,但这变成了一场噩梦。

谢谢!

更新 1:所以一些额外的花絮。

如果我将自定义控件更改为从 TextBox 而不是 UserControl 继承,则选项卡/焦点按预期工作。

如果我将其更改为 aControl而不是 aUserControl制表符也可以正常工作,但是焦点永远不会进入我内部的 TextBox - 焦点似乎丢失了(或者大概是在外部父控件上,但没有传递到内部文本框)。

我确实看到从 2009 年开始添加了一个描述此问题的 MS Connect 项目,但此链接似乎仅在我未登录 Microsoft Connect 时才有效。这意味着,我不能对其进行投票或评论... http://connect.microsoft.com/VisualStudio/feedback/details/472592/tab-cycling-through-controls-with-usercontrol-on-toolstrip-doesnt -按预期执行

Han*_*ant 5

.NET 2.0 ToolStripItem 类是一个主要的错误工厂。它们是无窗口控件,但重现Windows 窗口的确切行为并不容易。下面有大量代码,其中大部分是内部代码,因此您无法修改它。当他们不能完美地模拟窗口的行为时,就会出现怪癖。您可以称它们为“空域”问题,与 WPF 的问题类型非常相似。

这里的空域问题是focus,对于真正的窗口来说完全没有歧义,但它需要为 ToolStripItem 伪造。它实际上是具有焦点的项目的父项,需要为项目模拟它。字节的转换,ToolStrip 期望基于窗口的控件具有可靠的 Focus 属性。

问题是,您的自定义主机没有。重点是内部控制。这可以归咎于 ToolStripControlHost 类中的遗漏。大概。模拟窗口的麻烦,永远没有足够的代码:)

Anyhoo,通过将这段代码添加到您的主机来解决您的问题:

public override bool Focused {
    get { return _textBox.Focused; }
}
Run Code Online (Sandbox Code Playgroud)