2009-03-06 14 views
20

Ho un controllo WPF Popup che contiene alcuni controlli di modifica (caselle di riepilogo, caselle di testo, caselle di controllo) disposti con un po 'di spazio bianco.Perché un Popup WPF si chiude quando si fa clic sulla sua area di sfondo?

Popup.StaysOpen è impostato su False, che è richiesto. Se l'utente fa clic altrove nell'applicazione, l'operazione di modifica dovrebbe essere considerata interrotta e il popup dovrebbe chiudersi.

Sfortunatamente il popup si chiude anche quando l'utente fa clic nell'area di sfondo del popup (lo spazio tra i controlli di modifica).

Ho provato a impostare il popup su Focusable. Ho anche provato a mettere a fuoco il bambino del popup (a Border). Nessuna fortuna su entrambi i fronti.

Inoltre, l'evento del mouse sembra passare attraverso il popup. Qualunque elemento si trovi sotto il popup quando clicco, si focalizza. Ciò è possibile nonostante sia lo (nel quale sto facendo clic) sia con lo Popup sia con lo IsHitTestVisible e Focusable impostato su true.

risposta

28

Alla fine, ho scoperto che quanto segue funzionava. Dato ...

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

... Ho usato questo codice nel costruttore dopo aver chiamato 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 molto bello ed elegante! –

+1

Ottima soluzione! Ero persino in grado di farlo con un controllo definito su Generic.xaml, utilizzando EventToCommand, passando EventArgs al comando e quindi impostando Handled = True. Grazie! – Dror

+1

Un altro modo per infilare il gestore pari in un punto difficile è derivare una classe 'ArmouredPopup' che deriva da' Popup'. Può sovrascrivere 'OnMouseDown'. Considero questo un bug nella classe popup predefinita. –

0

La mia ipotesi migliore è che si verifichino problemi di trasparenza. Prova a impostare un pennello di sfondo sul popup.

+0

Grazie per la risposta. Il controllo del bordo riempie l'intera area del popup e ha un set di pennelli solido –

6

Sembra strano che sarebbe ignorare Focusable sul popup e di frontiera. Sono stato in grado di risolvere il problema modificando StaysOpen in un trigger quando il mouse si trova sopra il bordo:

<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

In realtà, questo funziona per me.Solo una cosa che è importante notare, @RobertMacnee, è che dovresti assicurarti di non impostare la proprietà 'StaysOpen' sull'elemento Popup stesso, dovrebbe essere lasciata allo style setter e triggerare completamente altrimenti non funzionerà . – Kezzer

1

Non hai il tuo Popup nidificato in un ToggleButton o di altro tipo di Button? Quindi arrestare l'evento indirizzato a livello di Popup sarebbe logico per funzionare.

0

è possibile impostare RIMANI_APERTO = true, e impostare un timer, nel caso in MouseLeave del Popup timer.Start(), ad esempio dopo 3 secondi, chiudere questo popup, in caso MouseEnter, timer.Stop(). Funzionerà.

Problemi correlati