2012-11-20 20 views
5

我發現了很多解釋冒泡的例子,但沒有一個關於隧道這是關於隧道,例如父母到孩子。我認爲我的主要問題是,我不明白如何註冊路由事件的子(WindowControl到UserControl)。 我:RoutedEvent隧道沒有到達孩子

public partial class MyParent : UserControl 
{ 
    public static readonly RoutedEvent RoutedMouseUpEvent = EventManager.RegisterRoutedEvent(
     "PreviewMouseLeftButtonUp", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(WindowControl)); 

// Provide CLR accessors for the event   
public event RoutedEventHandler MouseUp 
{ 
    add { AddHandler(RoutedMouseUpEvent, value); } 
    remove { RemoveHandler(RoutedMouseUpEvent, value); } 
} 

public addView(UserControl view) 
{ 
WindowControl win = new WindowControl(); 
win.Content = view; 
} 

private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
{ 
    RoutedEventArgs newEventArgs = new RoutedEventArgs(MyParent.RoutedMouseUpEvent); 
      RaiseEvent(newEventArgs); 
} 
} 

addView的封裝是必要的,應該沒問題吧?孩子通過addView添加。 Grid_MouseLeftButtonUp被調用。
接收器看起來是這樣的(這是MVVM所以沒有太多):

public partial class ChildView : UserControl 
{ 
void UserControl_PreviewMouseLeftButtonUp(object sender, RoutedEventArgs args) 
{ 
    int i = 0; // The breakpoint is never called 
} 
} 

在XAML

<Grid> 
    <Border BorderBrush="black" BorderThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center" PreviewMouseLeftButtonUp="UserControl_PreviewMouseLeftButtonUp"> 
</Border> 
</Grid> 

如果我忘了什麼事,請讓我知道。 問題是,路由事件沒有達到UserControl_PreviewMouseLeftButtonUp

回答

11

這不是隧道路由策略的工作原理。隧道意味着事件將從根開始並沿着樹形路徑進入呼叫控制。例如,如果我們有如下的可視化樹

Window 
| 
|--> SomeUserControl 
|--> MyParent 
    | 
    |--> ChildView 

那麼如果MyParent將提高隧道時,隧道事件將訪問:

  1. 窗口
  2. MyParent

NOT

  1. MyParent
  2. ChildView

所以總結一下,冒泡事件將始終啓動在控制引發事件,並停止在視覺樹的根,而隧道的事件將在視覺的根目錄開始樹並結束控制引發事件(完全相同的路徑,只有相反的順序)。

編輯:你可以在MSDN's Routed Events Overview閱讀更多關於路由事件。它也有一個很好的形象展示了這一點:

enter image description here

+0

我不明白。爲什麼我不能告訴程序MyParent是根? – Martin

+1

現在我明白了。隧道無法到達我的孩子,這使得我的看法毫無用處。我確實讀過這些碼頭,但不知怎的,這種方式不理解。我將使用Interfaces解決我的問題,並簡單地傳遞數據(這是計劃B)。謝謝你的優秀解釋。 – Martin

+1

隧道並非無用,它只是用於與您嘗試的任務不同的任務。例如,它可以用來禁止在文本框中鍵入某些字符,方法是捕獲按鍵並在事件到達文本框之前取消該事件。 –