我知道'Onclick'是Direct routed事件之一,
直接路由事件是由源本身处理的事件,但仍然不清楚所有直接路由事件是什么,所有在互联网上给出的示例仅使用'OnClick'进行直接路由事件。
有人可以提供所有直接路由事件的列表吗?
答案 0 :(得分:2)
我知道
OnClick
是直接路由事件之一
如果您指的是ButtonBase.OnClick
,那么它实际上不是直接事件;这是一个冒泡的事件。
TextChanged
是路由事件类别中的直接事件吗?
如果你指的是TextBox.TextChanged
,那么不;它也是一个冒泡的事件。
有人可以提供所有直接路由事件的列表吗?
从C#Interactive窗口轻松完成:
> #r "WindowsBase"
> #r "PresentationCore"
> #r "PresentationFramework"
> using System.Windows;
> using System.Linq;
> using System.Runtime.CompilerServices;
> var types = from t in typeof(FrameworkElement).Assembly.GetTypes()
. where typeof(FrameworkElement).IsAssignableFrom(t)
. select t;
> foreach (var t in types) RuntimeHelpers.RunClassConstructor(t.TypeHandle);
> var events = from e in EventManager.GetRoutedEvents()
. where e.RoutingStrategy == RoutingStrategy.Direct
. select $"{e.OwnerType.Name}.{e.Name}";
> foreach (var e in events) Console.WriteLine(e);
结果:
FrameworkElement.SizeChanged
FrameworkElement.Loaded
FrameworkElement.Unloaded
ToolTipService.ToolTipOpening
ToolTipService.ToolTipClosing
UIElement.PreviewMouseLeftButtonDown
UIElement.MouseLeftButtonDown
UIElement.PreviewMouseLeftButtonUp
UIElement.MouseLeftButtonUp
UIElement.PreviewMouseRightButtonDown
UIElement.MouseRightButtonDown
UIElement.PreviewMouseRightButtonUp
UIElement.MouseRightButtonUp
Mouse.MouseEnter
Mouse.MouseLeave
Stylus.StylusEnter
Stylus.StylusLeave
Touch.TouchEnter
Touch.TouchLeave
Control.PreviewMouseDoubleClick
Control.MouseDoubleClick
Calendar.SelectedDatesChanged
DatePicker.SelectedDateChanged
VirtualizingStackPanel.CleanUpVirtualizedItemEvent
请注意,上面的代码只会显示路由事件。它不会向您展示普通的旧CLR事件。
在你的结果中,PreviewMouseLeftButtonDown是一个直接事件,但据我所知它的隧道事件和类似的MouseLeftButtonDown是冒泡事件,请澄清。
这是一个直接的事件。检查源代码:
/// <summary>
/// Declaration of the routed event reporting the left mouse button was pressed
/// </summary>
public static readonly RoutedEvent PreviewMouseLeftButtonDownEvent =
EventManager.RegisterRoutedEvent("PreviewMouseLeftButtonDown",
RoutingStrategy.Direct,
typeof(MouseButtonEventHandler),
_typeofThis);
你的困惑可能源于它行为就像一个隧道事件。特定于按钮的鼠标事件是一种“子事件”&#39 ;;当某些其他事件到达给定的UI元素时,它们会被引发。例如,当LeftMouseButtonDown
到达MouseButtonDown
ChangedButton
时,Left
会被触发。 Preview
事件也是如此。
亲眼看看:
private static void OnPreviewMouseDownThunk(object sender, MouseButtonEventArgs e)
{
if(!e.Handled)
{
UIElement uie = sender as UIElement;
if (uie != null)
{
uie.OnPreviewMouseDown(e);
}
else
{
ContentElement ce = sender as ContentElement;
if (ce != null)
{
ce.OnPreviewMouseDown(e);
}
else
{
((UIElement3D)sender).OnPreviewMouseDown(e);
}
}
}
// Always raise this "sub-event", but we pass along the handledness.
UIElement.CrackMouseButtonEventAndReRaiseEvent((DependencyObject)sender, e);
}
private static void CrackMouseButtonEventAndReRaiseEvent(DependencyObject sender, MouseButtonEventArgs e)
{
RoutedEvent newEvent = CrackMouseButtonEvent(e);
if (newEvent != null)
{
ReRaiseEventAs(sender, e, newEvent);
}
}
private static RoutedEvent CrackMouseButtonEvent(MouseButtonEventArgs e)
{
RoutedEvent newEvent = null;
switch(e.ChangedButton)
{
case MouseButton.Left:
if(e.RoutedEvent == Mouse.PreviewMouseDownEvent)
newEvent = UIElement.PreviewMouseLeftButtonDownEvent;
else if(e.RoutedEvent == Mouse.MouseDownEvent)
newEvent = UIElement.MouseLeftButtonDownEvent;
else if(e.RoutedEvent == Mouse.PreviewMouseUpEvent)
newEvent = UIElement.PreviewMouseLeftButtonUpEvent;
else
newEvent = UIElement.MouseLeftButtonUpEvent;
break;
case MouseButton.Right:
if(e.RoutedEvent == Mouse.PreviewMouseDownEvent)
newEvent = UIElement.PreviewMouseRightButtonDownEvent;
else if(e.RoutedEvent == Mouse.MouseDownEvent)
newEvent = UIElement.MouseRightButtonDownEvent;
else if(e.RoutedEvent == Mouse.PreviewMouseUpEvent)
newEvent = UIElement.PreviewMouseRightButtonUpEvent;
else
newEvent = UIElement.MouseRightButtonUpEvent;
break;
default:
// No wrappers exposed for the other buttons.
break;
}
return ( newEvent );
}
因此,虽然按钮特定事件是直接事件,但它们会依赖于冒泡和隧道事件,因此它们出现以遵循这些路由策略。
对于所有意图和目的,您可以将它们视为冒泡和隧道事件,无论它们是如何注册的。