如何在 WPF 中使用 Interaction.EventTrigger 和冒泡自定义事件

How to use Interaction.EventTrigger and bubbling custom events in WPF

我正在尝试处理来自 UserControlRoutedEvent 我通过使用 Interaction.Triggers 将其连接到命令来构建它。以下作品——它调用 AddingNewThingCommand:

<WrapPanel>

    <local:MyCustomUserControl Header="MyHeader1"
                               ItemsSource="{Binding List1}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="AddingNewThing">
                <prism:InvokeCommandAction Command="{Binding DataContext.AddingNewThingCommand, ElementName=rootViewElement}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </local:MyCustomUserControl >

    <local:MyCustomUserControl Header="MyHeader2"
                               ItemsSource="{Binding List2}">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="AddingNewThing">
                <prism:InvokeCommandAction Command="{Binding DataContext.AddingNewThingCommand, ElementName=rootViewElement}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </local:MyCustomUserControl >

</WrapPanel>

现在我实际上在这个包装面板中有很多这样的用户控件实例,所以我更愿意将交互触发器移动到父元素 -- WrapPanel。以下不起作用:

<WrapPanel>
    <i:Interaction.Triggers>
        <!-- Also tried local:MyCustomUserControl.AddingNewThing -->
        <i:EventTrigger EventName="MyCustomUserControl.AddingNewThing">
            <prism:InvokeCommandAction Command="{Binding DataContext.AddingNewThingCommand, ElementName=rootViewElement}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>

    <local:MyCustomUserControl Header="MyHeader1"
                               ItemsSource="{Binding List1}"/>
    <local:MyCustomUserControl Header="MyHeader2"
                               ItemsSource="{Binding List2}"/>
</WrapPanel>

EventTrigger 是否适用于冒泡事件?

我的路由事件:

    public static readonly RoutedEvent AddingNewThingEvent = EventManager.RegisterRoutedEvent(
        "AddingNewThing", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyCustomUserControl));
    public event RoutedEventHandler AddingNewThing
    {
        add { AddHandler(AddingNewThingEvent, value); }
        remove { RemoveHandler(AddingNewThingEvent, value); }
    }

通常,路由事件系统允许将任何路由事件的处理程序附加到任何 UIElementContentElement。这就是路由事件的工作方式。

但是,System.Windows.Interactivity.EventTrigger 不是可视化树的一部分,因此无法参与此路由事件调度。 EventTrigger 使用给定的 EventName(使用反射:Type.GetEvent)直接订阅 CLR 事件。

将使用以下顺序确定事件源对象:

  1. 如果设置了 EventTriggerSourceObject 属性,请尝试获取该对象。如果它不为空,则使用它。
  2. 如果设置了 EventTriggerSourceName,则使用命名对象解析器获取对象。
  3. 否则,使用 EventTrigger 直接附加到的关联对象。

EventName 必须是一个简单的事件名称。不支持完全限定的事件名称(即 Type.EventName)。这与 System.Windows.EventTrigger 相反,您可以在 RoutedEvent 属性.

中指定完全限定的路由事件名称

所以简而言之,您不能以这种方式简化您的 WrapPanel。 也许你可以使用一个 ItemsControl 和一个 WrapPanel 作为 ItemsPanel 并定义一个 DataTemplate 包含你的 MyCustomUserControlEventTriggers.