如何:加入路由事件的類別處理
路由事件可由路由中任何指定節點上的類別處理程式或實例處理程式來處理。 類別處理程式會先被叫用,而且可由類別實作用來隱藏實例處理的事件,或針對基底類別所擁有的事件引入其他事件特定行為。 此範例說明實作類別處理程式的兩種密切相關的技術。
範例
此範例會根據 Canvas 面板使用自訂使用者帳戶類別。 應用程式的基本前提是,自定義類別會在其子元素上引入行為,包括攔截任何滑鼠左鍵點擊,並將點擊標記為已處理,再叫用子元素類別或其上的任何實例處理程式。
UIElement 類別會公開虛擬方法,只要覆寫事件,即可在 PreviewMouseLeftButtonDown 事件上啟用類別處理。 如果這類虛擬方法可在類別階層的某處使用,則這是實作類別處理最簡單的方法。 下列程式代碼顯示衍生自 Canvas 的 「MyEditContainer」 中的 OnPreviewMouseLeftButtonDown實作。 實作會將事件標示為於自變數中處理,然後新增一些程式代碼,讓來源元素有基本的可見變更。
protected override void OnPreviewMouseRightButtonDown(System.Windows.Input.MouseButtonEventArgs e)
{
e.Handled = true; //suppress the click event and other leftmousebuttondown responders
MyEditContainer ec = (MyEditContainer)e.Source;
if (ec.EditState)
{ ec.EditState = false; }
else
{ ec.EditState = true; }
base.OnPreviewMouseRightButtonDown(e);
}
Protected Overrides Sub OnPreviewMouseRightButtonDown(ByVal e As System.Windows.Input.MouseButtonEventArgs)
e.Handled = True 'suppress the click event and other leftmousebuttondown responders
Dim ec As MyEditContainer = CType(e.Source, MyEditContainer)
If ec.EditState Then
ec.EditState = False
Else
ec.EditState = True
End If
MyBase.OnPreviewMouseRightButtonDown(e)
End Sub
如果基底類別或該特定方法上沒有可用的虛擬,則可以使用 EventManager 類別的公用方法直接新增類別處理, RegisterClassHandler。 只有在新增類別處理的類別靜態初始化流程中,才應該呼叫這個方法。 本範例會為 PreviewMouseLeftButtonDown 新增另一個處理程式,在此案例中,已註冊的類別是自定義類別。 相反地,使用虛擬時,已註冊的類別實際上是 UIElement 基底類別。 在各個基底類別和子類別註冊類別處理的情況下,會先叫用子類別處理程式。 應用程式中的行為是,此處理程式會先顯示其訊息框,然後會顯示虛擬方法處理程式中的視覺變更。
static MyEditContainer()
{
EventManager.RegisterClassHandler(typeof(MyEditContainer), PreviewMouseRightButtonDownEvent, new RoutedEventHandler(LocalOnMouseRightButtonDown));
}
internal static void LocalOnMouseRightButtonDown(object sender, RoutedEventArgs e)
{
MessageBox.Show("this is invoked before the On* class handler on UIElement");
//e.Handled = true; //uncommenting this would cause ONLY the subclass' class handler to respond
}
Shared Sub New()
EventManager.RegisterClassHandler(GetType(MyEditContainer), PreviewMouseRightButtonDownEvent, New RoutedEventHandler(AddressOf LocalOnMouseRightButtonDown))
End Sub
Friend Shared Sub LocalOnMouseRightButtonDown(ByVal sender As Object, ByVal e As RoutedEventArgs)
MessageBox.Show("this is invoked before the On* class handler on UIElement")
'e.Handled = True //uncommenting this would cause ONLY the subclass' class handler to respond
End Sub