下面的方法是一樣的赫爾格·克萊因的,只是彈出自動關閉,當您單擊彈出(包括切換按鈕本身)以外的任何地方:
<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」中使用在IsHitTestVisible綁定,這樣當你再次點擊切換按鈕,在彈出的關閉:
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);
}
}
...其中一個顯示combining IValueConverter and MarkupExtension的方便的技術。
我確實發現了這種技術的一個問題:當兩個彈出窗口同時在屏幕上時,WPF會出現問題。具體來說,如果您的切換按鈕位於工具欄中的「溢出彈出窗口」中,那麼在您單擊它後會打開兩個彈出窗口。然後,您可能會發現,當您點擊窗口的其他任何位置時,第二個彈出窗口(您的彈出窗口)將保持打開狀態。那時,關閉彈出窗口很困難。用戶不能再次單擊ToggleButton來關閉彈出窗口,因爲IsHitTestVisible爲false,因爲彈出窗口已打開!在我的應用程序中,我不得不使用一些黑客來緩解這個問題,比如在主窗口中進行了以下測試,該測試說(在Louis Black的聲音中)「如果彈出窗口是打開的,並且用戶在彈出窗口外點擊某處,關閉受詛咒的彈出「。
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;
}
};
有趣的方法 – viggity 2009-06-04 15:50:34
也看到@ Qwertie的做法取代了
Storyboard
東西可以進一步簡化 - 受此啓發更有用的版本,它會自動您何時關閉彈出alt-tab或在彈出框外點擊 – 2012-01-30 02:16:19