Взаимодействие с формой без ее активации

Я пытаюсь реализовать всплывающее окно завершения кода в своем проекте. Окно является производным от Form. Он содержит два элемента управления: пользовательский список, полученный из UserControl (он показывает возможности завершения с помощью значков) и VScrollBar.

Когда всплывающее окно появляется, оно не крадет фокус у редактора (ShowWithoutActivation формы переопределяется, чтобы вернуть значение true), и редактор отправляет всплывающему окну определенные нажатия клавиш, чтобы пользователь мог взаимодействовать с ним с помощью клавиатуры. Пока это работает как шарм.

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

Есть ли способ взаимодействовать с всплывающей формой (с помощью мыши), который не активирует форму?

Документация ShowWithoutActivation гласит: «Если вашему неактивированному окну необходимо использовать элементы управления пользовательского интерфейса, вам следует рассмотреть возможность использования элементов управления ToolStrip, таких как ToolStripDropDown. Эти элементы управления не содержат окон и не вызывают активацию окна при их выборе». Это похоже на то, что мне нужно, но я хочу использовать настраиваемый элемент управления и полосу прокрутки.

Та же проблема будет с всплывающей подсказкой, которая показывает эти две стрелки для переключения перегрузок методов (известных из VS) - вся форма вообще не будет использовать элементы управления (только отображать текст и стрелки), но при нажатии она не должна активироваться . Проблема может быть сведена к «Как создать форму, которая никогда не будет активироваться, но позволит пользователю взаимодействовать с определенными элементами управления внутри?».

Спасибо.


person Xerxes    schedule 27.09.2009    source источник
comment
Вам нужно сделать это отдельной формой? Если бы вы реализовали это как пользовательский элемент управления, который плавал над всеми другими элементами управления в форме, у вас не было бы этой проблемы. Конечно, вы, вероятно, хотите, чтобы это всплывающее окно могло появляться за краями вашей формы.   -  person MusiGenesis    schedule 27.09.2009
comment
@MusiGenesis: Да, основная причина, по которой я делаю всплывающее окно отдельной формой, заключается в том, что оно может отображаться за краями. Мерцание — это только косметическая проблема, но опять же, этого не происходит в VS и подобных приложениях, поэтому должен быть способ...   -  person Xerxes    schedule 28.09.2009
comment
Я немного смущен. Вы хотите, чтобы пользователь взаимодействовал с мышью в плавающем окне, но не хотите придавать ему фокус? Я бы предложил не использовать форму и просто закодировать плавающий элемент управления, который все еще привязан к своему родителю.   -  person Andrew Keith    schedule 30.09.2009


Ответы (3)


Просто переопределите событие onFocus...

public partial class myListBox:ListBox
{
    protected override void OnGotFocus(EventArgs e)
    {
    }
}
person choudeshell    schedule 28.09.2009
comment
Спасибо, но это не работает, я пробовал это раньше. Если я вызываю _editor.Focus() как реакцию на события GotFocus или Activated, я больше не могу щелкнуть всплывающую форму - она ​​не отвечает. А мерцание все равно есть. Однако это работает, если я вызываю _editor.Focus() как реакцию на события MouseDown, но при этом строка заголовка редактора все еще мерцает. - person Xerxes; 28.09.2009

Проблема в том, что вы используете для этого форму, а не создаете какой-то настраиваемый элемент управления, который не работает в своем собственном потоке пользовательского интерфейса, как это делает форма. Мигание и выделение обрабатываются окнами всякий раз, когда форма активируется/фокусируется. Единственное, о чем я могу думать, это сделать вашу форму без полей и создать/нарисовать/обработать собственную строку заголовка, которая не мигает при фокусировке.

person TJF    schedule 30.09.2009

Хорошо, я, возможно, нашел решение. Ключ, кажется, является сообщением WM_MOUSEACTIVATE, которое всплывающая форма должна перехватить и ответить MA_NOACTIVATE. Но есть загвоздка — элемент управления, полученный из UserControl, по-прежнему захватывает фокус при нажатии (к счастью, полоса прокрутки больше не делает этого). Проблема, похоже, в методе UserControl.OnMouseDown, который внутренне фокусируется на элементе управления. Есть несколько способов это исправить:

  • получить элемент управления из Control вместо UserControl
  • переопределить метод OnMouseDown и не вызывать там base.OnMouseDown
  • заставить свойство элемента управления CanFocus возвращать false, но это кажется невозможным, потому что это означает, что элемент управления либо не виден, либо не включен, что нежелательно

Последний случай, когда всплывающая форма крадет фокус, кажется, когда ее изменение размера (с помощью мыши) заканчивается. Но здесь безопасно вызывать Owner.Activate() в результате события Activated...

person Xerxes    schedule 05.10.2009