是否可以使用带有附加事件的 Microsoft.Xaml.Behaviors.EventTrigger 调用命令?

Posted

技术标签:

【中文标题】是否可以使用带有附加事件的 Microsoft.Xaml.Behaviors.EventTrigger 调用命令?【英文标题】:Is it possible to use invoke a command using an Microsoft.Xaml.Behaviors.EventTrigger with attached events? 【发布时间】:2021-12-11 08:00:12 【问题描述】:

我正在尝试使用附加事件来调用 ICommand

我正在使用Microsoft.Toolkit.Mvvm NuGet 包以及Microsoft.Xaml.Behaviors.Wpf Nuget 包。

通过定义<EventTrigger /> 并将RoutedEvent 设置为与相关事件的名称相同,我已经成功地使用<FOO.Triggers /> 中的<BeginStoryBoardAction /> 启动了故事板。

但是,据我所知,无法使用<EventTrigger /> 中提供的任何内容来调用ICommand。我的意思是,我可以在 <EventTriggers.Actions /> 块的主体内使用任何东西(类似于 <Behaviors.InvokeCommandAction />),这将导致 ICommand 被调用。

按照最小、完整和可验证的示例,为了演示我想要实现的目标,您可以参考 GitHub 上的项目 - https://github.com/AbbottWC/MCVE_AttachedEventFailure。

或者

打开 Visual Studio。创建 WPF 应用程序(面向 .Net Core 3.1)

工具 -> NuGet 包管理器 -> 管理此解决方案的包

添加 Microsoft.Toolkit.Mvvm(用于 RelayCommand 类)和 Microsoft.Xaml.Behaviors.Wpf 包。

App.Xaml.cs

 private RelayCommand testCommand = new RelayCommand(( ) => MessageBox.Show("Event Captured!", "Success!"));
 public RelayCommand TestCommand => testCommand;

在 MainWindow.xaml 中

定义命名空间xmlns:i="http://schemas.microsoft.com/xaml/behaviors"

local 重命名为l

在关闭</Window> 标记之前将以下内容添加到 XAML 的正文中:

<i:Interaction.Triggers>
    <!--This will work, and is present only to prove the problem lies not with the Command or how it is being accessed.-->
    <i:EventTrigger EventName="MouseEnter">
        <i:EventTrigger.Actions>
            <i:InvokeCommandAction Command="Binding TestCommand, Source=x:Static l:App.Current" />
        </i:EventTrigger.Actions>
    </i:EventTrigger>
    <!--This will not work, and is meant to provide an example of the problem.-->
    <i:EventTrigger EventName="Mouse.MouseEnter">
        <i:EventTrigger.Actions>
            <i:InvokeCommandAction Command="Binding TestCommand, Source=x:Static l:App.Current" />
        </i:EventTrigger.Actions>
    </i:EventTrigger>
</i:Interaction.Triggers>

所以要重申我的问题,我想在这里实现的目标是否可行?就不能以这种方式使用附加事件吗?

谢谢。

【问题讨论】:

【参考方案1】:

据我了解,EventTrigger 只能监听源对象“拥有”的事件。因此,要回答您的问题,使用 EventTrigger 类是不可能的。

如果您查看source,当您传递Mouse.MouseEnter 时,它会尝试从目标类型中获取该事件。此外,由于您没有指定目标,它默认为AssociatedObject,在您的情况下为Window

Type targetType = obj.GetType();
EventInfo eventInfo = targetType.GetEvent(eventName);

现在我发现的问题是,如果它找不到事件,它只会在源对象不为空时抛出异常,并且在你的情况下你没有指定一个,所以它会默默地失败。不知道为什么设计师会这样做。

现在,我确实找到了这篇博文,它准确地描述了如何解决这个问题: https://sergecalderara.wordpress.com/2012/08/23/how-to-attached-an-mvvm-eventtocommand-to-an-attached-event/

基本上,您从EventTriggerBase&lt;T&gt; 继承,在OnAttached 方法中,您需要在AssociatedObject 上调用AddHandler 来添加事件。

【讨论】:

太棒了。我期待着尝试一下。感谢您的博客链接。哇……差不多 10 年前?

以上是关于是否可以使用带有附加事件的 Microsoft.Xaml.Behaviors.EventTrigger 调用命令?的主要内容,如果未能解决你的问题,请参考以下文章

带有 farbtastic 颜色选择器内容的 Twitter Bootstrap Popover.js 丢失了附加的事件

Google Calendar API,如何添加带有附加新生成的google meet的事件?

是否可以绘制带有箭头的图形,如 MATLAB 中附加的图像所示?

在ajax调用中附加tbody后点击事件不起作用?

如何检查动态附加的事件监听器是不是存在?

使用设计器 ASP.NET C# 将事件附加到占位符内的控件