2009-03-06 27 views
20

Tengo un control WPF Popup que contiene algunos controles de edición (cuadros de lista, cuadros de texto, casillas de verificación) dispuestos con bastante espacio en blanco.¿Por qué se cierra una ventana emergente WPF cuando se hace clic en su área de fondo?

Popup.StaysOpen se establece en False, que es obligatorio. Si el usuario hace clic en otra parte de la aplicación, la operación de edición debería considerarse abortada y la ventana emergente debería cerrarse.

Lamentablemente, la ventana emergente también se cierra cada vez que el usuario hace clic dentro de la región de fondo de la ventana emergente (el espacio entre los controles de edición).

He intentado configurar la ventana emergente para que sea Focusable. También intenté configurar el elemento secundario de la ventana emergente (un Border) para que se pueda enfocar. Sin suerte en ninguno de los frentes.

Además, el evento del mouse parece pasar por la ventana emergente. Cualquier elemento que se encuentre debajo de la ventana emergente cuando haga clic en él se enfoca. Esto a pesar de que tanto el Popup como el Border (en el que estoy haciendo clic) tienen IsHitTestVisible y Focusable establecidos en true.

Respuesta

28

Al final, me pareció que lo siguiente funcionó. Teniendo en cuenta ...

<Popup x:Name="_popup" 
     StaysOpen="False" 
     PopupAnimation="Slide" 
     AllowsTransparency="True"> 

... He utilizado este código en el constructor después de llamar InitializeComponent ...

// Ensure that any mouse event that gets through to the 
// popup is considered handled, otherwise the popup would close 
_popup.MouseDown += (s, e) => e.Handled = true; 
+0

+1 ¡muy bonito y elegante! –

+1

¡Gran solución! Incluso pude hacerlo con un control definido en Generic.xaml, usando EventToCommand, pasando los EventArgs al comando y luego configurando Handled = True. ¡Gracias! – Dror

+1

Otra forma de colar el controlador par en un punto complicado es derivar una clase 'ArmouredPopup' que se deriva de' Popup'. Puede anular 'OnMouseDown'. Considero que esto es un error en la clase emergente predeterminada. –

0

Supongo que tiene algunos problemas de transparencia. Intenta configurar un pincel de fondo en la ventana emergente.

+0

Gracias por su respuesta. El control de borde llena toda la región de la ventana emergente y tiene un conjunto de pinceles sólido –

6

Parece extraño que ignoraría enfocable en la ventana emergente y de frontera. Yo era capaz de solucionar el problema cambiando StaysOpen en un gatillo cuando el ratón está sobre la frontera:

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <ToggleButton x:Name="btnPop" Content="Pop!" Width="100" Height="50"/> 
    <Popup Placement="Bottom" PlacementTarget="{Binding ElementName=btnPop}" IsOpen="{Binding IsChecked, ElementName=btnPop}"> 
     <Popup.Style> 
      <Style TargetType="{x:Type Popup}"> 
       <Setter Property="StaysOpen" Value="False"/> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding IsMouseOver, ElementName=brd}" Value="True"> 
         <Setter Property="StaysOpen" Value="True"/> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </Popup.Style> 
     <Border x:Name="brd" Background="White" BorderThickness="1" BorderBrush="Black"> 
      <StackPanel> 
       <TextBox Margin="10"/> 
       <TextBlock Text="Some text is here." Margin="10"/> 
       <TextBox Margin="10"/> 
      </StackPanel>    
     </Border> 
    </Popup> 
</Grid> 
+0

En realidad, esto funciona para mí.Solo una cosa que es importante tener en cuenta, @RobertMacnee, es que debes asegurarte de no configurar la propiedad 'StaysOpen' en el elemento Popup en sí mismo, sino dejarlo en el formador de estilo y activarlo por completo, de lo contrario no funcionará. . – Kezzer

1

¿No tienes tu popup anidado en un ToggleButton u otro tipo de botón? Luego, detener el evento enrutado en el nivel emergente sería lógico para que funcione.

0

puede establecer stayopen = true, y establecer un temporizador, en el caso de la MouseLeave emergente timer.Start(), como después de 3 segundos, cerrar esta ventana emergente, en caso MouseEnter, timer.Stop(). Funcionará.

Cuestiones relacionadas