2017-12-02 48 views
0

我想創建一個觸發時Panel.OnVisualChildrenChanged被稱爲附着面板事件:我該如何提出一個附加的事件處理程序?

public class PanelObserver { 
    public static readonly RoutedEvent VisualChildrenChangedEvent; 

    static PanelObserver() { 
     VisualChildrenChangedEvent = EventManager.RegisterRoutedEvent(
      "VisualChildrenChanged", 
      RoutingStrategy.Bubble, 
      typeof(RoutedEventHandler), 
      typeof(Panel)); 
    } 

    public static void AddVisualChildrenChangedHandler(
     DependencyObject d, RoutedEventHandler handler) { 
     //Something needs to be done to d so that when OnVisualChildrenChanged is called, 
     //it will fire handler. 
     (d as Panel)?.AddHandler(VisualChildrenChangedEvent, handler); 
    } 

    public static void RemoveVisualChildrenChangedHandler(
     DependencyObject d, RoutedEventHandler handler) { 
     //Something will likely need to be done to d here as well... 
     (d as Panel)?.RemoveHandler(VisualChildrenChangedEvent, handler); 
    } 
} 

使用情況是相當直截了當

<Grid myns:PanelObserver.VisualChildrenChanged = "SomeEventHandler" /> 

理想情況下,事件將每次Panel.OnVisualChildrenChanged是提高調用。如果可能的話,我需要添加到AddVisualChildrenChanged方法(以及它的對映)以實現此目的嗎?如果這不是如何實現這一點,那麼完成這個的適當方法是什麼?

回答

0

我不能想辦法通過可附着的面板事件觸發Panel.OnVisualChildrenChanged。 相反,您可以從任何Panel類派生並覆蓋OnVisualChildrenChanged,然後聲明另一個事件。

例如:

public class ObservablePanel : Panel 
{ 
    protected override void OnVisualChildrenChanged(DependencyObject visualAdded, DependencyObject visualRemoved) 
    { 
     base.OnVisualChildrenChanged(visualAdded, visualRemoved); 
     VisualChildrenChanged?.Invoke(this, EventArgs.Empty); 
    } 
    public event EventHandler VisualChildrenChanged; 
} 

爲什麼你無法通過可連接面板事件做的原因:
1. Panel.Children屬性是UIElementCollection不公開任何事件捕捉,如果它「改變」。
2. Panel.Children屬性爲只讀屬性,因此您無法將其設置爲UIElementCollection的自定義派生實現,該實現將顯示「已更改」事件。
3. Panel.OnVisualChildrenChangedprotected因此您只能在Panel派生類上訪問它。

+0

謝謝。這太愚蠢了。似乎是一個非常重要的疏忽,不要讓某些方法檢測.Net團隊對面板內容的更改。 – Will

相關問題