2009-10-12 11 views
11

Tengo un C# ComboBox usando WPF. Tengo un código que se ejecuta cuando está activado el ComboBoxGotFocus. El problema es que el evento GotFocus se ejecuta cada vez que se realiza una selección desde ComboBox. Por ejemplo, el GotFocus se ejecuta cuando hace clic por primera vez en ComboBox y luego cuando hace una selección aunque no haya hecho clic en ningún otro control.C# ComboBox GotFocus

Es posible evitar que este evento se active si se realiza una selección en la lista o hay un indicador u otra cosa en el controlador de eventos que se puede usar para determinar si el controlador de eventos GotFocus se activó como resultado del usuario seleccionando un elemento en la lista?

+0

Buena información en esta otra pregunta. http://stackoverflow.com/questions/830510/issue-with-wpf-focus [link] (http://stackoverflow.com/questions/830510/issue-with-wpf-focus) – Mikeb

Respuesta

0

No estoy demasiado caliente en WPF; pero si está tratando de detectar cambios en la lista (haga clic en el nuevo valor, etc.) puede usar los eventos SelectedIndexChanged ..

Por otro lado, si realmente desea saber simplemente cuándo se enfoca el control, puede lo filtra diciendo algo como;

if (combo1.Focused && combo1.SelectedIndex == -1) 
{ 
    ... 
} 

..? Realmente depende de lo que estás tratando de detectar, exactamente.

13

Puede resolver este problema con la siguiente verificación:

private void myComboBox_GotFocus(object sender, RoutedEventArgs e) 
{ 
    if (e.OriginalSource.GetType() == typeof(ComboBoxItem)) 
     return; 
    //Your code here 
} 

Este código filtrará todos los eventos de foco de artículos (porque utilizan evento de enrutamiento de burbujas). Pero hay otro problema: el comportamiento específico de WPF ComboBox focus: cuando abres la lista desplegable con elementos, tu ComboBox pierde el foco y los elementos se ponen. Cuando selecciona algún elemento, el elemento pierde el foco y ComboBox vuelve. La lista desplegable es como otro control. Esto se puede ver por código simple:

private void myComboBox_GotFocus(object sender, RoutedEventArgs e) 
{ 
    if (e.OriginalSource.GetType() != typeof(ComboBoxItem)) 
    { 
     Trace.WriteLine("Got " + DateTime.Now); 
    } 
} 

private void myComboBox_LostFocus(object sender, RoutedEventArgs e) 
{ 
    if (e.OriginalSource.GetType() != typeof(ComboBoxItem)) 
    { 
     Trace.WriteLine("Lost " + DateTime.Now); 
    } 
} 

por lo que obtendrá de todos modos al menos dos eventos de foco: cuando se selecciona ComboBox y cuando se selecciona algo en él (enfoque volverá al cuadro combinado).

Para filtrar el enfoque devuelto después de seleccionar el elemento, puede intentar utilizar los eventos DropDownOpened/DropDownClosed con algún indicador de campo.

Así que el código final con sólo 1 caso de conseguir el enfoque:

private bool returnedFocus = false; 

private void myComboBox_GotFocus(object sender, RoutedEventArgs e) 
{ 
    if (e.OriginalSource.GetType() != typeof(ComboBoxItem) && !returnedFocus) 
    { 
     //Your code. 
    } 
} 

private void myComboBox_LostFocus(object sender, RoutedEventArgs e) 
{ 
    if (e.OriginalSource.GetType() != typeof(ComboBoxItem)) 
    { 
     ComboBox cb = (ComboBox)sender; 
     returnedFocus = cb.IsDropDownOpen; 
    } 
} 

elegir de esta ejemplos de lo que realmente se necesita más para su aplicación.

+0

Muchas gracias por la gran explicación! –

+0

Muchas gracias ... –

0

Otra solución que se usa es determinar si el nuevo elemento enfocado es un elemento existente en el cuadro combinado. Si es verdadero, el evento LostFocus no se debe realizar, porque el cuadro combinado todavía tiene foco. De lo contrario, un elemento fuera del cuadro combinado recibió el foco.

En el código snipplet continuación he añadido la funcionalidad en una clase de cuadro combinado a medida

public class MyComboBox : System.Windows.Controls.Combobox 
{ 
    protected override void OnLostFocus(RoutedEventArgs e) 
    { 
     //Get the new focused element and in case this is not an existing item of the current combobox then perform a lost focus command. 
     //Otherwise the drop down items have been opened and is still focused on the current combobox 
     var focusedElement = FocusManager.GetFocusedElement(FocusManager.GetFocusScope(this)); 
     if (!(focusedElement is ComboBoxItem && ItemsControl.ItemsControlFromItemContainer(focusedElement as ComboBoxItem) == this)) 
     { 
      base.OnLostFocus(e); 
      /* Your code here... */ 
     } 
    } 
}