1

我目前正在尝试 C# WPF 自定义路由事件,但遇到了问题。这就是我想要做的:我想从我的主窗口触发一个自定义路由事件,该事件通过堆栈面板隧道到由 Button 类派生的自定义控件。然后自定义控件处理路由事件。

我的问题是当我触发事件时,处理程序从未被调用过。

我的代码:

    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 代码:

<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>
4

2 回答 2

3

好的,我自己想出来了:虽然我已经读了一千遍了,但它在 MSDN 描述中清楚地说明了:

隧道:最初,调用元素树根处的事件处理程序。然后,路由事件沿着路由穿过连续的子元素,到达作为路由事件源的节点元素(引发路由事件的元素)。[...]

我对隧道路由事件的第一个想法是:我从主窗口触发一个事件,它通过堆栈面板到达按钮元素。 但改为: 您必须已经从按钮触发它 - 然后它从根元素(主窗口)开始,并通过控制层到达首先触发事件的按钮元素。

我所做的是:我从主窗口触发了事件,所以它不能去其他任何地方

于 2012-07-05T18:57:23.907 回答
0

此注册似乎不正确:

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

您需要public event ReoutedEventHandler MyRoutedEvent在此处注册的类中添加 。这应该是非静态类实例级处理程序。我在你的代码上没有看到。

你需要在 MainWindow 上这样的东西:

public event RoutedEventHandler MyRoutedEvent;

请参阅此处的 MSDN 示例。

于 2012-07-04T23:26:14.670 回答