В моем интерфейсе Silverlight у меня есть кнопка, при нажатии которой появляется элемент управления с некоторыми параметрами фильтрации. Я хотел бы, чтобы этот элемент управления скрывался, когда вы щелкаете за его пределами. Другими словами, он должен функционировать так же, как поле со списком, но это не поле со списком (вы не выбираете элемент в нем). Вот как я пытаюсь зафиксировать щелчок за пределами элемента управления, чтобы закрыть его:
public partial class MyPanel : UserControl
{
public MyPanel()
{
InitializeComponent();
}
private void FilterButton_Click(object sender, RoutedEventArgs e)
{
// Toggle the open state of the filter popup
FilterPopup.IsOpen = !FilterPopup.IsOpen;
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
// Capture all clicks and close the popup
App.Current.RootVisual.MouseLeftButtonDown += delegate {
FilterPopup.IsOpen = false; };
}
}
К сожалению, обработчик событий для MouseLeftButtonDown
никогда не запускается. Существует ли хорошо зарекомендовавший себя способ создания всплывающего элемента управления, который автоматически отключается, когда вы щелкаете за его пределами? Если нет, то почему мой обработчик MouseLeftButtonDown
не запускается?
Решение:
Я думал, что выложу все свое решение, если другие найдут его полезным. В моем визуальном изображении верхнего уровня я объявляю «щит» для всплывающих окон, например:
<UserControl xmlns:my="clr-namespace:Namespace"
x:Class="Namespace.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
xmlns:uriMapper="clr-namespace:System.Windows.Navigation;assembly=System.Windows.Controls.Navigation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
>
<Grid Background="Black" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<my:MyStuff/>
<Canvas HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
x:Name="PopupShield" Background="Transparent" Width="Auto"
Height="Auto" Visibility="Collapsed"/>
</Grid>
</UserControl>
Затем я добавил метод расширения для класса Popup
, например:
public static class PopupUtils
{
public static void MakeAutoDismissing(this Popup popup)
{
var shield = (App.Current.RootVisual as MainPage).PopupShield;
// Whenever the popup opens, deploy the shield
popup.HandlePropertyChanges(
"IsOpen",
(s, e) =>
{
shield.Visibility = (bool)e.NewValue
? Visibility.Visible : Visibility.Collapsed;
}
);
// Whenever the shield is clicked, dismiss the popup
shield.MouseLeftButtonDown += (s, e) => popup.IsOpen = false;
}
}
public static class FrameworkUtils
{
public static void HandlePropertyChanges(
this FrameworkElement element, string propertyName,
PropertyChangedCallback callback)
{
//Bind to a depedency property
Binding b = new Binding(propertyName) { Source = element };
var prop = System.Windows.DependencyProperty.RegisterAttached(
"ListenAttached" + propertyName,
typeof(object),
typeof(UserControl),
new System.Windows.PropertyMetadata(callback));
element.SetBinding(prop, b);
}
}
Метод расширения используется следующим образом:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
FilterPopup.MakeAutoDismissing();
}