2013-01-10 12 views
16

Sto provando a fare qualcosa che sembra relativamente semplice e logica da un livello di interfaccia utente, ma ho un bug che è molto fastidioso. Ho un ToggleButton e sto cercando di mostrare un Popup quando il pulsante è attivato e nasconde il Popup quando il pulsante è disattivato. Lo Popup si nasconde anche quando l'utente fa clic su di esso.Come associare correttamente un Popup a un ToggleButton?

Tutto sta funzionando come previsto con il seguente XAML, tranne quando si fa clic sul pulsante di commutazione dopo il Popup viene mostrato, il Popup sparisce per una frazione di secondo poi riappare.

Ho il sospetto che quello che sta succedendo qui è che facendo clic su di esso il Popup sta causando di disattivare il pulsante e quindi immediatamente dopo che il pulsante è stato attivato quando il mouse lo fa clic. Non so come procedere per risolverlo.

Qualsiasi aiuto è apprezzato. Grazie.

<ToggleButton x:Name="TogglePopupButton" Content="My Popup Toggle Button" Width="100" /> 

    <Popup StaysOpen="False" IsOpen="{Binding IsChecked, ElementName=TogglePopupButton, Mode=TwoWay}"> 
     <Border Width="100" Height="200" Background="White" BorderThickness="1" BorderBrush="Black"> 
      <TextBlock>This is a test</TextBlock> 
     </Border>     
    </Popup> 
+0

Questo non dovrebbe essere difficile come è. –

risposta

28

Le risposte di Stephan hanno lo svantaggio che scompare anche il comportamento desiderato di chiusura del popup ogni volta che perde la messa a fuoco.

Ho risolto disattivando il pulsante di attivazione quando il popup è aperto. Un'alternativa sarebbe quella di utilizzare la proprietà IsHitTestVisible invece è abilitato:

<ToggleButton x:Name="TogglePopupButton" Content="My Popup Toggle Button" Width="100" IsEnabled="{Binding ElementName=ToggledPopup, Path=IsOpen, Converter={StaticResource BoolToInvertedBoolConverter}}"/> 
    <Popup x:Name="ToggledPopup" StaysOpen="False" IsOpen="{Binding IsChecked, ElementName=TogglePopupButton, Mode=TwoWay}"> 
     <Border Width="100" Height="200" Background="White" BorderThickness="1" BorderBrush="Black"> 
      <TextBlock>This is a test</TextBlock> 
     </Border>     
    </Popup> 

Il convertitore è simile al seguente:

public class BoolToInvertedBoolConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (value is bool) 
     { 
      bool boolValue = (bool)value; 
      return !boolValue; 
     } 
     else 
      return false; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException("ConvertBack() of BoolToInvertedBoolConverter is not implemented"); 
    } 
} 
+3

Molto intelligente. Ho usato il metodo IsHitTestVisibile perché abbiamo bisogno di IsEnabled per altri motivi. – craftworkgames

+3

Questo risolve il problema, ma la soluzione apparentemente dipende da alcuni tempi complicati. Quando sostituisco il convertitore con associazione modello vista equivalente, non funziona più. Apparentemente button down set IsOpen = false, riabilitando ToggleButton, e button up attiva il ToggleButton. Non ho idea del perché la versione del convertitore funzioni. Temo che i tempi potrebbero bombardare più tardi quando verrà rilasciata una nuova versione del framework o quando questa soluzione verrà utilizzata in modi non banali. –

+0

@ RobertVažan Ho inserito il popup in un controllo personalizzato e ora ho riscontrato il problema specificato. Funziona se il popup fa parte del controllo esterno come dà questa risposta. –

-1

Set StaysOpen="True" per il vostro Popup

Da MSDN:

Ottiene o imposta un valore che indica se il controllo Popup chiude quando il controllo non è più a fuoco.

[...]

true se il controllo Popup chiude quando IsOpen proprietà è impostata false;

false se il controllo Popup si chiude quando si verifica un evento del mouse o della tastiera all'esterno del controllo Popup.

+3

L'effetto desiderato è di chiudere il popup quando la messa a fuoco è persa. Il problema è quando si usa un 'ToggleButton' per aprire' Popup', e si tenta di chiudere 'Popup' facendo clic su' ToggleButton'. Eseguirà l'azione di 'StaysOpen =" False "' e il clic del 'ToggleButton' causerà la chiusura del' Popup' e quindi l'apertura di nuovo. – deloreyk

11

soluzione senza IValueConverter:

<Grid> 
    <ToggleButton x:Name="TogglePopupButton" Content="My Popup Toggle Button" Width="100" > 
     <ToggleButton.Style> 
      <Style TargetType="{x:Type ToggleButton}"> 
       <Setter Property="IsHitTestVisible" Value="True"/> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding ElementName=Popup, Path=IsOpen}" Value="True"> 
         <Setter Property="IsHitTestVisible" Value="False"/> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </ToggleButton.Style> 
    </ToggleButton> 

    <Popup StaysOpen="false" IsOpen="{Binding IsChecked, ElementName=TogglePopupButton, Mode=TwoWay}" 
       PlacementTarget="{Binding ElementName=TogglePopupButton}" PopupAnimation="Slide" 
      x:Name="Popup"> 
     <Border Width="100" Height="200" Background="White" BorderThickness="1" BorderBrush="Black"> 
      <TextBlock>This is a test</TextBlock> 
     </Border> 
    </Popup> 
</Grid> 
+0

Questa soluzione funziona perfettamente e mi impedisce di scrivere un altro convertitore . Ottimo lavoro! –

0

Sulla ToggleButton impostare il Proprietà ClickMode="Press"apixeltoofar

+0

Sembra funzionare alla prima occhiata, ma mentre si fa clic sul pulsante ToggleButton non si riapre più il Popup, facendo clic in qualsiasi altro punto non si riesce improvvisamente a chiudere il Popup come previsto. Non capisco perché esattamente si tratti di questo problema e se sia risolvibile, ma non riesco a farlo funzionare. –