Tôi đã phải đối mặt với sự hiểu lầm tiếp theo.MouseButtonEventArgs.MouseDevice.DirectlyOver sự hiểu lầm
Preamble:
Tôi có WPF ứng dụng với tới phần giao diện người dùng thiết yếu: RadioButtons
và một số điều khiển mà sử dụng thả xuống dựa trên Popup
(theo cách combobox). Theo một số logic, mỗi móc nối vô tuyến PreviewMouseDown
sự kiện và thực hiện một số phép tính. Trong kịch bản tiếp theo,
- tài mở cửa sổ bật lên (không chọn một cái gì đó, bật lên chỉ ở mở)
- tài nhấp chuột vào radiobutton
PreviewMouseDown
sẽ không bị đuổi vì RadioButton như mong đợi (vì của Popup
feature).
Và mục đích của tôi là bắn PreviewMouseDown
cho RadioButton
bất kể một.
nỗ lực để giải quyết:
nhanh và bẩn giải pháp là: treo PreviewMouseDown
cho Popup
và tái lửa PreviewMouseDown
kiện với nguồn mới nếu cần thiết, sử dụng RadioButton như nguồn. Có thể lấy nguồn mới qua MouseButtonEventArgs.MouseDevice.DirectlyOver
. Các mảnh tiếp theo của mã làm điều đó (sự kiện được tái sa thải chỉ khi Popup
"ăn" PreviewMouseDown
cho nhấp chuột bên ngoài):
private static void GrantedPopupPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
var popup = sender as Popup;
if(popup == null)
return;
var realSource = e.MouseDevice.DirectlyOver as FrameworkElement;
if(realSource == null || !realSource.IsLoaded)
return;
var parent = LayoutTreeHelper.GetParent<Popup>(realSource);
if(parent == null || !Equals(parent, popup))
{
e.Handled = true;
var args = new MouseButtonEventArgs(e.MouseDevice,
e.Timestamp,
e.ChangedButton)
{
RoutedEvent = UIElement.PreviewMouseDownEvent,
Source = e.MouseDevice.DirectlyOver,
};
realSource.RaiseEvent(args);
}
}
này hoạt động tốt khi tôi đang gắn handler đó để Popup.PreviewMouseDown
trực tiếp qua Behavior
và không làm việc (PreviewMouseDown
không được sa thải vì radioButton) nếu tôi gắn một qua EventManager.RegisterClassHandler
(mục đích là để tránh đính kèm hành vi cho mọi Popup
có thể occure trên trang với những radiobuttons):
EventManager.RegisterClassHandler(
typeof (Popup),
PreviewMouseDownEvent,
new MouseButtonEventHandler(GrantedPopupPreviewMouseDown));
Trình gỡ lỗi cho thấy rằng e.MouseDevice.DirectlyOver
(xem mã ở trên) là Popup
, không phải Radiobutton
(vì đó là khi tôi đã đính kèm trình xử lý qua Behavior
)!
Câu hỏi:
Làm thế nào và tại sao MouseButtonEventArgs
có thể khác nhau đối với các hành động tương tự, nếu eventhandler gắn theo hai cách khác nhau?
Ai đó có thể phát hiện hành vi này không?
Cảm ơn rất nhiều.
Có một trường hợp thử nghiệm tái sản xuất tối thiểu trong XAML cho điều đó đối với chúng tôi chơi? Có thể có một sự nhầm lẫn về những gì Xem trước có nghĩa là trong bối cảnh WPF. Khi Xem trước * Sự kiện là các sự kiện đường hầm và bạn có thể muốn sử dụng Sự kiện MouseDown vì theo mặc định, bạn sẽ sủi bọt lên cây thị giác của mình – Samuel
Bạn có thể đăng XAML cho Popup và RadioButton của mình không? Giống như Samuel nói, đây là một vấn đề với đường hầm và các sự kiện sủi bọt. Sự kiện này đang được xử lý trên Popup trước khi nó thậm chí có thể đạt được Radiobutton là dự đoán của tôi. –
Chỉ cần đâm trong bóng tối, nhưng sẽ giống như công việc này? - Trình xử lý sự kiện MouseDown cho popup => popup.Close(); Trình xử lý sự kiện MouseUp cho radiobutton => làm việc của bạn. Ý tưởng là một MouseClick bao gồm hai hành động, hành động MouseDown đầu tiên sẽ đóng cửa sổ bật lên và hành động MouseUp thứ hai sau đó sẽ được chụp bằng nút radio ... – Marko