c# - Evitar el desplazamiento cuando el mouse entra en el menú desplegable ComboBox de WPF
.net .net-4.5 (3)
Cuando un ComboBox
tiene una gran cantidad de elementos, su menú desplegable se convertirá en desplazable. Cuando el usuario invoca este menú desplegable y mueve el cursor del mouse para ingresar los límites del menú desplegable desde la parte inferior, el menú desplegable desplaza inmediatamente uno o más elementos hacia abajo en la lista ( desde goobering: también ocurre al salir de los límites por el borde inferior ).
Este desplazamiento no es intuitivo, ya que la lista no se desplaza hacia arriba al ingresar los límites desde la parte superior.
¿Cómo podemos deshabilitar el comportamiento de desplazamiento automático?
En Visual Studio, este comportamiento se puede observar a través del menú desplegable de miembros en la barra de navegación del editor de código ( CTRL + F2 ).
La respuesta seleccionada de Andrew Hanlon evita que la lista se desplace al elemento seleccionado cuando se abre. También tuve que agregar esto al controlador de eventos ("lista" es el ComboBox):
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;
// Allows to bring the selected item into view:
if (((ComboBoxItem)e.TargetObject).Content == list.SelectedItem)
return;
e.Handled = true;
}
Por lo que puedo decir, esto parece deberse a que los elementos en la parte inferior de la luz se muestran "parcialmente", donde el contenedor trunca un elemento. Cuando el mouse pasa sobre un elemento parcial como este, WPF desplaza todo el elemento para verlo, lo que a veces puede dejar otro elemento parcial en la parte inferior.
En Winforms, esto se puede arreglar configurando .IntegralHeight
, pero no existe tal propiedad en WPF por lo que puedo decir. Si todos los elementos de su cuadro combinado tienen la misma altura, puede vincular la altura de la lista del cuadro combinado a un múltiplo de la altura del elemento, por ejemplo, mostrar elementos de 10 x 20px, configúrelo en 200.
Una forma de resolver esto es usar un Comportamiento (o más bien una Propiedad Adjunta similar a un comportamiento) para suscribirse al evento RequestBringIntoView
de los ComboBoxItems
y luego establecer el RequestBringIntoViewEventArgs.Handled
en true. Esto también se puede hacer a pequeña escala usando un EventSetter
y 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;
}
Editar
Descubrí que puede obtener el mismo efecto manejando el evento RequestBringIntoView en el ItemsPanel
de elementos en lugar de los propios elementos. Pero mismo resultado:
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel RequestBringIntoView="OnRequestBringIntoView"/>
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>