Trong giao diện người dùng Silverlight của tôi, tôi có một nút khi nhấp vào bật lên một điều khiển với một số thông số lọc. Tôi muốn điều khiển này tự ẩn khi bạn nhấp vào bên ngoài. Nói cách khác, nó sẽ hoạt động theo cách tương tự như hộp tổ hợp, nhưng nó không phải là một hộp kết hợp (bạn không chọn một mục trong đó). Đây là cách tôi đang cố gắng để nắm bắt một nhấp chuột bên ngoài sự kiểm soát để bỏ qua nó:Làm cách nào để loại bỏ cửa sổ bật lên trong Silverlight khi nhấp vào bên ngoài kiểm soát?
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; };
}
}
Thật không may, xử lý sự kiện cho MouseLeftButtonDown
không bao giờ bị sa thải. Có cách nào được thiết lập tốt để tạo điều khiển bật lên tự động loại bỏ khi bạn nhấp vào bên ngoài không? Nếu không, tại sao không phải là việc xử lý số MouseLeftButtonDown
của tôi?
Giải pháp:
tôi nghĩ rằng tôi muốn gửi toàn bộ giải pháp của tôi trong trường hợp người khác tìm thấy nó hữu ích. Trong top-level của tôi hình ảnh, tôi tuyên bố một "lá chắn" cho các quảng cáo, như thế này:
<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>
Sau đó, tôi đã thêm một phương pháp mở rộng cho lớp Popup
, như thế này:
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);
}
}
Các phương pháp mở rộng được sử dụng như thế này:
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
FilterPopup.MakeAutoDismissing();
}
Giải pháp của bạn đã hiệu quả đối với tôi. Nó sẽ là tốt hơn để tạo ra một giao diện với một tài sản duy nhất PopupShield và sử dụng điều này trong phương pháp MakeAutoDismissing. MainPage của bạn hoặc UserControl khác sẽ phải triển khai thuộc tính và trả về Canvas trong suốt. (Tại sao không đăng giải pháp của bạn như một câu trả lời để mọi người có thể bỏ phiếu cho nó?) – kgiannakakis