When a ComboBox
has a large number of items, its dropdown will become scrollable. When the user invokes this dropdown, and moves the mouse cursor to enter the bounds of the dropdown from the bottom, the dropdown immediately scrolls one or more items down the list (from goobering: also happens when exiting the bounds via the bottom edge).
This scrolling is not intuitive, as the list does not scroll upwards when entering the bounds from the top.
How can we disable the automatic scrolling behavior?
In Visual Studio this behavior can be observed via the member dropdown on the code editor's navigation bar (CTRL+F2).
One way to solve this is to use a Behaviour (or rather behaviour-like Attached Property) to subscribe to the RequestBringIntoView
event of the ComboBoxItems
and then set the RequestBringIntoViewEventArgs.Handled
to true.
This can also be done on a small scale using an EventSetter
and codebehind.
<Style TargetType="ComboBoxItem">
<EventSetter Event="RequestBringIntoView" Handler="OnRequestBringIntoView"/>
</Style>
private void OnRequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
//Allows the keyboard to bring the items into view as expected:
if (Keyboard.IsKeyDown(Key.Down) || Keyboard.IsKeyDown(Key.Up))
return;
e.Handled = true;
}
Edit
I found that you can get the same effect by handling the RequestBringIntoView event on the ItemsPanel
rather than the items themselves. But same result:
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel RequestBringIntoView="OnRequestBringIntoView"/>
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>