Handle tunneled custom routed event

2019-06-05 05:20发布

I'm currently experimenting with C# WPF custom routed events i got stuck at a problem. This is what i want to do: I want to fire a custom routed event from my main window which tunnels through a stackpanel to a custom control derived by the Button class. The custom control then handles the routed event.

My problem is when i fire the event the handler is never been called.

My code:

    public partial class MainWindow : Window
        {

        public static readonly RoutedEvent MyRoutedEvent = EventManager.RegisterRoutedEvent("MyRoutedEvent", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(UIElement));

        public static void AddMyRoutedEventHandler(DependencyObject d, RoutedEventHandler handler)
        {
            UIElement uie = d as UIElement;
            if (uie != null)
            {
                uie.AddHandler(MainWindow.MyRoutedEvent, handler);
            }
        }

        public static void RemoveMyRoutedEventHandler(DependencyObject d, RoutedEventHandler handler)
        {
            UIElement uie = d as UIElement;
            if (uie != null)
            {
                uie.RemoveHandler(MainWindow.MyRoutedEvent, handler);
            }
        }


        public MainWindow()
        {
            InitializeComponent();
        }

        private void keyClassButton1_MyRoutedEvent(object sender, RoutedEventArgs e)
        {
            Console.Write("\nMyRoutedEvent!");
        }

        private void Window_MouseDown(object sender, MouseButtonEventArgs e)
        {
            RoutedEventArgs newEventArgs = new RoutedEventArgs(MyRoutedEvent, this);
            RaiseEvent(newEventArgs);
        }
    }

XAML code:

<Window x:Class="RoutedEvent_Test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:RoutedEvent_Test"
        Title="MainWindow" Height="350" Width="525" MouseDown="Window_MouseDown">
    <Grid>
        <StackPanel Name="stackPanel1">
            <local:KeyClass x:Name="keyClass1" Content="key class button" Height="30" local:MainWindow.MyRoutedEvent="keyClassButton1_MyRoutedEvent"></local:KeyClass>
        </StackPanel>
    </Grid>
</Window>

2条回答
混吃等死
2楼-- · 2019-06-05 05:50

This registration doesn't seem to be correct:

public static readonly RoutedEvent MyRoutedEvent = EventManager.RegisterRoutedEvent("MyRoutedEvent", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(UIElement));

You need to add the public event ReoutedEventHandler MyRoutedEvent in the class as you registered here. This should be non static class instance level handler. I don't see it on your code.

You need need something like this on the MainWindow:

public event RoutedEventHandler MyRoutedEvent;

See MSDN example here.

查看更多
贪生不怕死
3楼-- · 2019-06-05 06:02

ok i figured it out by myself: Although i've read it like a thousand times it clearly states in the MSDN description:

Tunneling: Initially, event handlers at the element tree root are invoked. The routed event then travels a route through successive child elements along the route, towards the node element that is the routed event source (the element that raised the routed event). [...]

My first idea of a tunneled routed event was: I fire a event from the main window and it goes through the stackpanel to the button element. BUT INSTEAD: You have to fire it from the button already - then it begins at the root element (main window) and goes through the control layers to the button element which fired the event in the first place.

What i did was: I fired the event from the main window so it couldn't go anywhere else

查看更多
登录 后发表回答