擷取滑鼠滾輪事件的簡單行為
實現行為
當內部事件處於其上限或下限時,此行為將導致內部 ScrollViewer
的滑鼠滾輪事件冒泡到父 ScrollViewer
。如果沒有這種行為,事件將永遠不會超出內部的時間。
public class BubbleMouseWheelEvents : Behavior<UIElement>
{
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.PreviewMouseWheel += PreviewMouseWheel;
}
protected override void OnDetaching()
{
this.AssociatedObject.PreviewMouseWheel -= PreviewMouseWheel;
base.OnDetaching();
}
private void PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
var scrollViewer = AssociatedObject.GetChildOf<ScrollViewer>(includeSelf: true);
var scrollPos = scrollViewer.ContentVerticalOffset;
if ((scrollPos == scrollViewer.ScrollableHeight && e.Delta < 0) || (scrollPos == 0 && e.Delta > 0))
{
UIElement rerouteTo = AssociatedObject;
if (ReferenceEquals(scrollViewer, AssociatedObject))
{
rerouteTo = (UIElement) VisualTreeHelper.GetParent(AssociatedObject);
}
e.Handled = true;
var e2 = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);
e2.RoutedEvent = UIElement.MouseWheelEvent;
rerouteTo.RaiseEvent(e2);
}
}
}
行為是 Behavior<T>
基類的子類,T
是它能夠附加的控制元件型別,在本例中為 UIElement
。當從 XAML 例項化 Behavior
時,呼叫 OnAttached
方法。此方法允許行為掛鉤來自它所附加的控制元件的事件(通過 AssociatedControl
)。類似的方法,當需要從關聯元素取消掛鉤行為時,呼叫 OnDetached
。應注意刪除任何事件處理程式,或以其他方式清理物件以避免記憶體洩漏。
此行為會掛鉤到 PreviewMouseWheel
事件,該事件會在 ScrollViewer
有機會檢視之前對其進行更改以攔截事件。它檢查位置以檢視是否需要將事件沿可視樹轉發到任何更高層次的層次。如果是這樣,它將 e.Handled
設定為 true
以防止事件的預設操作。然後它提出了一個新的 MouseWheelEvent
路由到 AssociatedObject
。否則,事件將正常路由。
將行為附加到 XAML 中的元素
首先,必須先將 interactivity
xml-namespace 引入範圍,然後才能在 XAML 中使用它。將以下行新增到 XAML 的名稱空間。
xmlns:interactivity =“ http://schemas.microsoft.com/expression/2010/interactivity ”
可以像這樣附加行為:
<ScrollViewer>
<!--...Content...-->
<ScrollViewer>
<interactivity:Interaction.Behaviors>
<behaviors:BubbleMouseWheelEvents />
</interactivity:Interaction.Behaviors>
<!--...Content...-->
</ScrollViewer>
<!--...Content...-->.
</ScrollViewer>
這將建立一個 Behaviors
集合作為內部 ScrollViewer
上的附加屬性,其中包含 BubbleMouseWheelEvents
行為。
此特定行為也可以附加到包含嵌入式 ScrollViewer
的任何現有控制元件,例如 GridView
,並且它仍然可以正常執行。