ToolStrip с пользовательским ToolStripControlHost делает фокус на порядок вкладок странным

У меня странное поведение. Позвольте мне попытаться объяснить, я сократил свой код до минимума, и у меня все еще есть проблема. Итак, во-первых, я использую VS2013 с.NET 4.0 и я на Windows 8.1.

Так что у меня есть обычай UserControl с TextBox это используется через 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); } }
}

Простое создание нового проекта WinForms (.NET4) и выполнение этих шагов позволит вам воспроизвести проблему:

  1. Добавьте новый файл класса и вставьте код выше.
  2. строить
  3. Добавить ToolStrip к вашей форме
  4. В ToolStrip добавьте кнопку, мой пользовательский элемент управления и еще одну кнопку (через дизайнера, как я это делал)
  5. Бежать

После запуска...

  1. Фокус в пользовательском контроле
  2. Нажмите несколько раз TAB, он должен сосредоточиться только на элементах управления слева.
  3. Нажмите SHIFT+TAB несколько раз, и он будет фокусироваться только вправо.

Кто-нибудь знает в чем проблема - или как я могу это исправить? Я весь день рвал на себе волосы, пытаясь это исправить. Я наконец-то сократил свой код и, похоже, не могу заставить его работать. Я даже пытался переопределить большую часть OnEnter/OnGotFocus функциональность и делать это сам, но это стало кошмаром.

Спасибо!

Обновление 1: Итак, несколько дополнительных битов.

Если я изменю пользовательский элемент управления на наследование от TextBox вместо UserControl, табуляция / фокусировка будут работать как положено.

Если я изменю это, чтобы быть Control вместо UserControl Вкладка также работает нормально, однако фокус никогда не попадает внутрь моего внутреннего TextBox - кажется, что фокус потерян (или предположительно на внешнем родительском элементе управления, но не передан во внутренний TextBox).

Я вижу добавленный элемент MS Connect, описывающий эту проблему с 2009 года, но эта ссылка работает, только если я НЕ вошел в Microsoft Connect. Это значит, что я не могу голосовать за это или комментировать... http://connect.microsoft.com/VisualStudio/feedback/details/472592/tab-cycling-through-controls-with-usercontrol-on-toolstrip-doesnt-perform-as-expected

1 ответ

Решение

Классы.NET 2.0 ToolStripItem стали основной фабрикой ошибок. Это элементы управления без окон, но воспроизвести точное поведение окна Windows не так просто. Внизу огромное количество кода, большая часть которого внутренняя, поэтому вы не сможете с ним повозиться. И с причудами, когда они не полностью имитируют поведение окна. Вы могли бы назвать их проблемами "воздушного пространства", очень похожими на те проблемы, которые есть у WPF.

Проблема воздушного пространства здесь - это фокус, совершенно недвусмысленный для настоящего окна, но его необходимо подделать для ToolStripItem. Это на самом деле родитель элемента, который имеет фокус, его нужно эмулировать для элемента. Это переход, который байты, ToolStrip ожидает, что элемент управления на основе окна будет иметь надежное свойство Focus.

Проблема в том, что ваш пользовательский хост не делает. Это внутренний контроль, который имеет фокус. Возможно, это можно объяснить упущением в классе ToolStripControlHost. Наверное. Проблема с эмуляцией окна, там никогда не хватает кода:)

Anyhoo, исправьте свою проблему, добавив этот кусочек кода на ваш хост:

public override bool Focused {
    get { return _textBox.Focused; }
}
Другие вопросы по тегам