Правильный способ сделать туннельное событие

РЕДАКТИРОВАТЬ: Я думаю, я задал немного проблемы XY. Меня не волнует, как работают туннельные события, и мне важно получить событиеподнял из кода позади родительского окна быть поднятым и отреагированным элементом управления, который является дочерним элементом этого окна, без явной необходимости сообщать дочернему элементу, кто является его родителем, и вручную подписываться на событие.

Я пытаюсь вызвать событие в родительском элементе управления и заставить дочерние элементы управления прослушивать это событие и реагировать на него. Из моего исследования я подумал, что мне просто нужно сделатьRoutedEvent но я делаю что-то неправильно.

Вот MCVE, показывающий, что я пробовал, это простая программа с окном и UserControl внутри него.

<Window x:Class="RoutedEventsTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:RoutedEventsTest"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Button Name="button" Click="ButtonBase_OnClick" HorizontalAlignment="Left" 
                VerticalAlignment="Top">Unhandled in parent</Button>
        <local:ChildControl Grid.Row="1"/>
    </Grid>
</Window>
using System.Windows;

namespace RoutedEventsTest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            TestEventHandler += MainWindow_TestEventHandler;
        }

        void MainWindow_TestEventHandler(object sender, RoutedEventArgs e)
        {
            button.Content = "Handeled in parent";
            e.Handled = false;
        }

        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            RaiseEvent(new RoutedEventArgs(TestEvent));
        }

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

        public event RoutedEventHandler TestEventHandler
        {
            add { AddHandler(TestEvent, value); }
            remove { RemoveHandler(TestEvent, value); }
        }
    }
}
<UserControl x:Class="RoutedEventsTest.ChildControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
          <TextBlock Name="textBlock">Unhandeled in child</TextBlock>  
    </Grid>
</UserControl>
using System.Windows;
using System.Windows.Controls;

namespace RoutedEventsTest
{
    public partial class ChildControl : UserControl
    {
        public ChildControl()
        {
            InitializeComponent();
            AddHandler(MainWindow.TestEvent, new RoutedEventHandler(TestEventHandler));
        }

        private void TestEventHandler(object sender, RoutedEventArgs routedEventArgs)
        {
            textBlock.Text = "Handled in child";
            routedEventArgs.Handled = false;
        }
    }
}

Когда я запускаю программу, родительское окно реагирует так, как я ожидал, но дочерний UserControl никогда не запускает свой делегат, которому я передалAddHandler.

Изменение дочернего элемента управления, чтобы быть

public partial class ChildControl : UserControl
{
    public ChildControl()
    {
        InitializeComponent();
        AddHandler(TestEvent, new RoutedEventHandler(TestEventHandler));
    }

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

    private void TestEventHandler(object sender, RoutedEventArgs routedEventArgs)
    {
        textBlock.Text = "Handled in child";
        routedEventArgs.Handled = false;
    }
}

не решил проблему также. Я много искал и нашел много примеров того, как сделать пузырьковое событие, переходящее от ребенка к родителю, но я не смог найти ни одного полного примера, показывающего, как сделать туннельное событие от родителя к ребенку.

Ответы на вопрос(1)

Ваш ответ на вопрос