如何引发附加的事件处理程序?

时间:2017-12-02 22:32:54

标签: c# wpf xaml attached-properties

我想创建一个可附加的Panel事件,在调用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方法(以及它的对映体)中添加什么来实现这一目标?如果这不是如何实现这一点,那么实现这一目标的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

我无法想出通过可附加的Panel事件触发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,如果事件发生变化,则不会公开任何事件。#34;。
2. Panel.Children属性是只读的,因此您无法将其设置为UIElementCollection的自定义派生实现,该实现将公开&#34;已更改&#34;事件。
3. Panel.OnVisualChildrenChangedprotected,因此您只能在Panel派生类上访问它。