我该如何提出一个附加的事件处理程序?

问题描述:

我想创建一个触发时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方法(以及它的对映)以实现此目的吗?如果这不是如何实现这一点,那么完成这个的适当方法是什么?

我不能想办法通过可附着的面板事件触发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