Подтвердить что ты не робот

Как элемент управления может управлять щелчком мыши за пределами этого элемента управления?

Я пишу настраиваемый элемент управления, и я бы хотел, чтобы элемент управления переключился с состояния редактирования на нормальное состояние, когда пользователь отключился от элемента управления. Я обрабатываю событие LostFocus, и это помогает, когда пользователь уходит или нажимает на другой элемент управления, который является Focusable. Но если они не нажимают на что-то Focusable, оно не будет отключать его состояние редактирования. Поэтому у меня есть два решения:

  • Поднимите дерево до самого верхнего элемента, когда он войдет в состояние редактирования, и добавьте обработчик для MouseDownEvent (и обработайте "обработанные" события). В обработчике я удалил бы из него состояние редактирования и удалял обработчик из самого верхнего элемента. Это кажется немного взломанным, но, вероятно, это будет хорошо работать.

Пример кода:

private void RegisterTopMostParentMouseClickEvent()
{
   _topMostParent = this.FindLastVisualAncestor<FrameworkElement>();
   if ( _topMostParent == null )
      return;
   _topMostParent.AddHandler( Mouse.MouseDownEvent, new MouseButtonEventHandler( CustomControlMouseDownEvent ), true );
}

private void UnRegisterTopMostParentMouseClickEvent()
{
   if ( _topMostParent == null )
      return;
   _topMostParent.RemoveHandler( Mouse.MouseDownEvent, new MouseButtonEventHandler( CustomControlMouseDownEvent ) );
   _topMostParent = null;
}
  • Используйте Mouse.PreviewMouseDownOutsideCapturedElement и добавьте обработчик к моему элементу управления. В обработчике я удалил бы контроль из этого состояния редактирования. Но, похоже, я не собираюсь возбуждать это событие. Когда вызывается Mouse.PreviewMouseDownOutsideCapturedElement?

Пример кода:

AddHandler( Mouse.PreviewMouseDownOutsideCapturedElementEvent, new MouseButtonEventHandler( EditableTextBlockPreviewMouseDownOutsideCapturedElementEvent ), true );
4b9b3361

Ответ 1

Захват мыши. Когда объект захватывает мышь, все связанные с мышью события обрабатываются так, как если бы объект с захватом мыши выполнял событие, даже если указатель мыши находится над другим объектом.

Ответ 2

Просто, чтобы прояснить ответ, предоставленный в отношении фокуса мыши - это было полезно, но я должен был сделать еще одно копание + выкидывание, чтобы получить что-то, что действительно сработало:

Я пытался реализовать что-то вроде combobox и нуждался в подобном поведении - чтобы получить падение вниз, чтобы исчезнуть при нажатии на что-то еще, без контроля, знающего, что что-то еще.

У меня было следующее событие для кнопки "вниз":

    private void ClickButton(object sender, RoutedEventArgs routedEventArgs)
    {
        //do stuff (eg activate drop down)
        Mouse.Capture(this, CaptureMode.SubTree);
        AddHandler();
    }

CaptureMode.SubTree означает, что вы получаете только события, которые находятся вне элемента управления, и любая активность мыши в элементе управления передается в обычное состояние. У вас нет возможности предоставить этот Enum в UIElement CaptureMouse, это означает, что вы вызовете HandleClickOutsideOfControl INSTEAD вызовы для любых дочерних элементов управления или других обработчиков внутри элемента управления. Это так, даже если вы не подписываетесь на события, которые они используют - полный захват мыши слишком много!

    private void AddHandler()
    {
        AddHandler(Mouse.PreviewMouseDownOutsideCapturedElementEvent, new MouseButtonEventHandler(HandleClickOutsideOfControl), true);
    }

Вам также нужно будет держаться + удалять обработчик в соответствующих точках, но я оставил его здесь для ясности/краткости.

Наконец, в обработчике вам нужно снова освободить захват.

    private void HandleClickOutsideOfControl(object sender, MouseButtonEventArgs e)
    {
        //do stuff (eg close drop down)
        ReleaseMouseCapture();
    }

Ответ 3

Я бы подошел к этому по-другому - получив форму, содержащую элемент управления, удалите фокус с элемента управления, когда пользователь нажимает на другую часть формы.

Наличие элемента управления на самом деле. Свободный фокус намного чище, чем попытка сбросить фокус в определенных ситуациях, когда на самом деле это не так. Имейте в виду, что, если элемент управления не потерял фокус, он все равно примет такие вещи, как ввод с клавиатуры.

Ответ 4

Обычно я получаю родительское окно и добавляю обработчик предварительного просмотра, даже если он уже обработан. Иногда, когда MouseCapture недостаточно, этот метод подходит:

Window.GetWindow(this).AddHandler
(
    UIElement.MouseDownEvent,
    (MouseButtonEventHandler)TextBox_PreviewMouseDown,
    true
);