2011-04-28 8 views
9

Tengo un control que contiene un Togglebutton y un Popup. Cuando se hace clic en ToggleButton, aparece la ventana emergente. Cuando el ToggleButton está desmarcado, la ventana emergente debe cerrarse. Además, al hacer clic fuera de la ventana emergente se debe cerrar y hacer que Togglebutton se desmarque.Interacción emergente y Togglebutton en wpf

He configurado esto estableciendo la propiedad StaysOpen del Popup en falso, y estableciendo la propiedad IsChecked del botón de alternar para que esté enlazado bidireccionalmente a la propiedad IsOpen del Popup.

Todo está bien, aparte de un caso: con el botón marcado y la ventana emergente abierta, al hacer clic en el botón no se cierra la ventana emergente o el botón vuelve a estar desmarcado.

Creo que esto debe ser porque hacer clic en el botón hace que la lógica StaysOpen del Popup establezca la propiedad IsOpen de la ventana emergente en falso. A su vez, esto establece el Togglebutton sin marcar. Esto debe suceder antes de que se haga clic en el botón, de modo que el clic vuelve a verificar el botón, es decir, una condición de carrera.

¿Alguna idea de cómo puedo obtener el comportamiento que quiero?

Respuesta

9

Si su suposición es correcta, que había necesidad de una clase emergente personalizado como el siguiente:

public class MyPopup : Popup { 
    protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) { 
     bool isOpen = this.IsOpen; 
     base.OnPreviewMouseLeftButtonDown(e); 

     if (isOpen && !this.IsOpen) 
      e.Handled = true; 
    } 
} 

Es posible que tenga que quitar la !this.IsOpen de la sentencia if. Si usa MyPopup en su lugar, evitará que el evento MouseLeftButtonDown llegue al ToggleButton.

+0

que es perfecto, gracias. –

+1

Un problema con este enfoque es que si hace clic fuera de la ventana emergente, en realidad no hace clic en nada. No desea hacer clic en 'ToggleButton', pero desea hacer clic en todo lo demás – svick

1

La solución es establecer una unión entre la TwoWay IsOpen propiedad de la ventana emergente y la IsChecked propiedad del ToggleButton - A continuación, establezca la ClickMode propiedad del ToggleButton a Prensa. Voila!

+3

no funciona tampoco ... cliquear fuera de ventana emergente no cierra popup – mike01010

+0

@ mike01010 Creo firmemente que este es un error ... – torvin

7

Ambas soluciones anteriores tienen problemas. Aquí hay otra solución que utiliza controladores de eventos en lugar de vinculantes, pero evita el problema de clics perdidos señalado por svick con la solución MyPopup y los problemas con ClickMode = Press. El xaml parece:

<ToggleButton Name="OptionsButton" Checked="OptionsButton_OnChecked" Unchecked="OptionsButton_OnUnchecked" /> 
<Popup Name="OptionsPopup" StaysOpen="False" Closed="OptionsPopup_OnClosed"/> 

Y código:

void OptionsPopup_OnClosed(object sender, EventArgs e) 
    { 
     if (OptionsButton != Mouse.DirectlyOver) 
      OptionsButton.IsChecked = false; 
    } 

    void OptionsButton_OnChecked(object sender, RoutedEventArgs e) 
    { 
     OptionsPopup.IsOpen = true; 
    } 

    void OptionsButton_OnUnchecked(object sender, RoutedEventArgs e) 
    { 
     OptionsPopup.IsOpen = false; 
    } 
+3

Puede deshacerse de los controladores OnChecked y OnUnchecked vinculando OptionsPopup.IsOpen to OptionsButton.IsChecked, a.la. ''. Asegúrese de configurar ** 'Mode = OneWay' **. – kcnygaard

Cuestiones relacionadas