Die folgende Vorgehensweise ist die gleiche wie Helge Klein, mit der Ausnahme, dass das Popup automatisch schließt, wenn Sie irgendwo außerhalb des Popup klicken (einschließlich der ToggleButton selbst):
<ToggleButton x:Name="Btn" IsHitTestVisible="{Binding ElementName=Popup, Path=IsOpen, Mode=OneWay, Converter={local:BoolInverter}}">
<TextBlock Text="Click here for popup!"/>
</ToggleButton>
<Popup IsOpen="{Binding IsChecked, ElementName=Btn}" x:Name="Popup" StaysOpen="False">
<Border BorderBrush="Black" BorderThickness="1" Background="LightYellow">
<CheckBox Content="This is a popup"/>
</Border>
</Popup>
"BoolInverter" verwendet wird in die IsHitTestVisible Bindung, so dass, wenn Sie die ToggleButton erneut auf, schließt sich das Popup:
public class BoolInverter : MarkupExtension, IValueConverter
{
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool)
return !(bool)value;
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return Convert(value, targetType, parameter, culture);
}
}
... welche die handliche Technik von combining IValueConverter and MarkupExtension in einem zeigt.
Ich habe ein Problem mit dieser Technik entdeckt: WPF ist fehlerhaft, wenn zwei Popups gleichzeitig auf dem Bildschirm sind. Genauer gesagt, wenn sich die Umschalttaste im "Überlauf-Popup" in einer Symbolleiste befindet, werden zwei Popups geöffnet, nachdem Sie darauf geklickt haben. Sie werden dann feststellen, dass das zweite Popup (Ihr Popup) geöffnet bleibt, wenn Sie irgendwo anders auf Ihr Fenster klicken. An diesem Punkt ist das Schließen des Popups schwierig. Der Benutzer kann nicht erneut auf den ToggleButton klicken, um das Popup zu schließen, da IsHitTestVisible false ist, weil das Popup geöffnet ist! In meiner App musste ich ein paar Hacks verwenden, um dieses Problem zu mildern, wie den folgenden Test im Hauptfenster, der sagt (in der Stimme von Louis Black): "Wenn das Popup geöffnet ist und der Benutzer irgendwo außerhalb des Popups klickt, schließen sie die friggin Popup ".
PreviewMouseDown += (s, e) =>
{
if (Popup.IsOpen)
{
Point p = e.GetPosition(Popup.Child);
if (!IsInRange(p.X, 0, ((FrameworkElement)Popup.Child).ActualWidth) ||
!IsInRange(p.Y, 0, ((FrameworkElement)Popup.Child).ActualHeight))
Popup.IsOpen = false;
}
};
interessanter Ansatz – viggity
siehe auch @ Qwertie Ansatz beschrieben Eventtrigger Aktion mit einem benutzerdefinierten Material vereinfacht werden - eine nützlichere Version von dieser inspiriert, dass das Popup automatisch geschlossen wird, wenn Sie alt-Tab oder klicken Sie außerhalb des Popup –