PeejayAdams Ответов: 1

Как остановить автоматический выбор с помощью клавиши со стрелкой вниз в выпадающем списке WPF?


У меня есть контроль поиска, основанный на ComboBox. Элемент управления фильтрует его содержимое в соответствии с содержимым текстовой части выпадающего списка.

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

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

Мой ComboBox выглядит так:

<ComboBox Name="cbUsers" VerticalAlignment="Top" HorizontalContentAlignment="Stretch" Grid.Row="1" Grid.Column="0" IsEditable="True" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=my:Recipients, AncestorLevel=1}, Path=FilteredUsers}" IsTextSearchEnabled="False"  Focusable="True"   ScrollViewer.CanContentScroll="True" TextBoxBase.TextChanged="cbUsers_TextChanged" SelectionChanged="cbUsers_SelectionChanged" ToolTip="Begin typing name or enter initials to find user.">
</ComboBox>


Что я уже пробовал:

Я попытался добавить PreviewKeyUp в ComboBox и установить e. Handled в true, если клавиша-стрелка вниз. Это срабатывает, но не имеет никакого эффекта.

Я также попытался добавить обработчик непосредственно в часть текстового поля:

TextBox textBox = (TextBox)cbUsers.Template.FindName("PART_EditableTextBox", cbUsers);
textBox.PreviewKeyUp += new System.Windows.Input.KeyEventHandler(textBox_PreviewKeyUp);


Опять же, это срабатывает, но не останавливает автоматический выбор.

1 Ответов

Рейтинг:
7

PureNsanity

Причина, по которой добавление делегата в событие preview up заключается в том, что это многоадресный делегат - все они увольняются. С помощью маршрутизируемых событий вы можете остановить запуск других событий, установив для Аргументов событий значение обработано.

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

Конечно, если вы предварительно просмотрите событие key up при нажатии стрелки вниз, оно никогда не будет запущено. Что-то просматривает это событие, распознает, что это стрелка вниз, и устанавливает handled в true. Имеет смысл в этом случае нормально правильно?

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

if (e.Source is ComboBox && e.Key == Key.Down)
{
    e.Handled = true;
}


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


PeejayAdams

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