Как узнать, когда контекстное меню текстового поля по умолчанию собирается открываться или закрываться? - PullRequest
7 голосов
/ 15 апреля 2011

Как узнать, когда собирается открываться контекстное меню текстового поля по умолчанию (до его открытия) или после его закрытия (не до, после)? События ContextMenuOpening и ContextMenuClosing, похоже, не срабатывают, когда я использую стандартное встроенное меню. Я предполагаю, что я мог бы просто воссоздать меню и заполнить его стандартными командами, но это кажется немного излишним.

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

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

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

Имеет смысл?

M


ОБНОВЛЕНИЕ: Технически на этот вопрос не было ответа, хотя я пометил его как таковой, поскольку ответчики помогли мне решить мою проблему. Но что касается самого вопроса здесь, похоже, что ответ «Вы не можете».

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

<ContextMenu x:Key="DefaultTextBoxContextMenu">
    <MenuItem Command="ApplicationCommands.Cut" />
    <MenuItem Command="ApplicationCommands.Copy" />
    <MenuItem Command="ApplicationCommands.Paste" />
</ContextMenu>

... и прикрепить его вот так ...

<TextBox x:Name="EditTextBox"
    ContextMenu="{StaticResource DefaultTextBoxContextMenu}"
    ContextMenuOpening="EditTextBox_ContextMenuOpening"
    ContextMenuClosing="EditTextBox_ContextMenuClosing" />

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

M

Ответы [ 2 ]

6 голосов
/ 15 апреля 2011

Когда контекстное меню текстового поля открывается, текстовое поле теряет фокус клавиатуры, но сохраняет логический фокус. Другими словами, его событие LostKeyboardFocus сработает, а событие LostFocus - нет. Свойство IsFocused текстового поля остается истинным, когда открыто контекстное меню. Исходя из вашего описания проблемы, вы должны иметь возможность полагаться на логическую направленность, чтобы определить, когда закончить «режим редактирования» в вашем элементе управления.

1 голос
/ 15 апреля 2011

По умолчанию TextBox по-прежнему сообщает true для IsFocused, в то время как контекстное меню по умолчанию открыто, но сообщает false для IsKeyboardFocused. То есть LostFocus не вызывается на TextBox при открытии контекстного меню, но будет вызываться, если контекстное меню закрывается при выборе какого-либо другого элемента управления. Это звучит как поведение, которое вы ищете.

Вы можете показать это поведение по умолчанию с помощью небольшой тестовой программы:

<Grid>
    <StackPanel>
        <TextBox Text="Some text one"
                 GotFocus="TextBox_GotFocus"
                 LostFocus="TextBox_LostFocus"/>
        <TextBox Text="Some text two"/>
    </StackPanel>
</Grid>

и код:

    private void TextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        Debug.WriteLine("GotFocus");
    }

    private void TextBox_LostFocus(object sender, RoutedEventArgs e)
    {
        Debug.WriteLine("LostFocus");
    }

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...