根據this MSDN article(等等),爲什麼在實例處理程序之前不會將此類處理程序附加到隧道事件?
類處理程序之前任何實例偵聽處理程序 附加到那個類,每當路由事件 到達在其路由中元素實例的一個實例被調用。
我是很新的RoutedEvent
這麼有機會的話,我在我的代碼有錯誤,但它好像附着於被聲明爲RoutingStrategy.Tunnel
一個RoutedEvent
類處理程序不總是在實例處理程序附加到同一事件之前觸發。
在我的例子中,我創建了一個TouchButton
控制類,其中有一個隧道RoutedEvent
和冒泡RoutedEvent
。我爲每個註冊了類處理程序。然後我在窗口中創建了一個類的實例,並在後面的代碼中處理每個事件。我在類元素和包含它的Grid
上爲隧道事件附加了相同的處理程序。所有四個處理程序在MessageBox
中顯示其名稱,以便您可以清楚地看到執行順序。
- 網格實例PreviewTouch
- 類TouchButton_PreviewTouch
- TouchButton實例PreviewTouch
- 類TouchButton_Touch
- TouchButton實例觸摸
這意味着,如果我叫e.Handled = true;
在類PreviewTouch
事件處理程序,我可以停止執行所有其他的事情r事件處理程序除了附加到Grid
元素之外的事件處理程序。這應該是這樣,還是我在某個地方犯了錯誤?否則,我怎樣才能停止執行每個實例事件處理程序?
這裏是類:
public class TouchButton : Button
{
static TouchButton()
{
EventManager.RegisterClassHandler(typeof(TouchButton), PreviewTouchEvent,
new RoutedEventHandler(TouchButton_PreviewTouch), true);
EventManager.RegisterClassHandler(typeof(TouchButton), TouchEvent,
new RoutedEventHandler(TouchButton_Touch), true);
}
private static void TouchButton_PreviewTouch(object sender, RoutedEventArgs e)
{
MessageBox.Show("Class TouchButton_PreviewTouch");
}
private static void TouchButton_Touch(object sender, RoutedEventArgs e)
{
MessageBox.Show("Class TouchButton_Touch");
}
public static RoutedEvent TouchEvent = EventManager.RegisterRoutedEvent("Touch",
RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TouchButton));
public event RoutedEventHandler Touch
{
add { AddHandler(TouchEvent, value); }
remove { RemoveHandler(TouchEvent, value); }
}
public static RoutedEvent PreviewTouchEvent = EventManager.RegisterRoutedEvent(
"PreviewTouch", RoutingStrategy.Tunnel, typeof(RoutedEventHandler),
typeof(TouchButton));
public event RoutedEventHandler PreviewTouch
{
add { AddHandler(PreviewTouchEvent, value); }
remove { RemoveHandler(PreviewTouchEvent, value); }
}
protected override void OnClick()
{
RaiseTouchEvent();
}
private void RaiseTouchEvent()
{
RoutedEventArgs touchEventArgs = new RoutedEventArgs(PreviewTouchEvent);
RaiseEvent(touchEventArgs);
if (!touchEventArgs.Handled) RaiseEvent(new RoutedEventArgs(TouchEvent));
}
}
這裏是在後面的窗口代碼實例句柄:
private void TouchButton_PreviewTouch(object sender, RoutedEventArgs e)
{
MessageBox.Show(string.Format("{0} Instance PreviewTouch",
((FrameworkElement)sender).Name));
}
private void TouchButton_Touch(object sender, RoutedEventArgs e)
{
MessageBox.Show(string.Format("{0} Instance Touch",
((FrameworkElement)sender).Name));
}
這裏是控制XAML:
<Grid Name="Grid" Controls:TouchButton.PreviewTouch="TouchButton_PreviewTouch">
<Controls:TouchButton x:Name="TouchButton" Width="200" Height="45" FontSize="24"
Content="Touch me" Touch="TouchButton_Touch" PreviewTouch="TouchButton_PreviewTouch" />
</Grid>
我明白隧道事件由Grid
元素在'隧道化'到之前處理元素,但我認爲類處理程序總是應該在實例處理程序之前觸發。如果不是,我該如何做到這一點?
UPDATE >>>
感謝@樂觀的答案,我設法找到一種方法來阻止所有的實例句柄從處理事件。如果不是與Grid
的樂觀建議更換的TouchButton
聲明類處理類型,我FrameworkElement
替換它,然後它會捕捉所有FrameworkElement
來源的控制。
EventManager.RegisterClassHandler(typeof(FrameworkElement), PreviewTouchEvent,
new RoutedEventHandler(TouchButton_PreviewTouch), true);
不錯的問題... – sanguine 2012-02-17 10:46:34