是否可以使用带有附加事件的 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<T>
继承,在OnAttached
方法中,您需要在AssociatedObject
上调用AddHandler
来添加事件。
【讨论】:
太棒了。我期待着尝试一下。感谢您的博客链接。哇……差不多 10 年前?以上是关于是否可以使用带有附加事件的 Microsoft.Xaml.Behaviors.EventTrigger 调用命令?的主要内容,如果未能解决你的问题,请参考以下文章
带有 farbtastic 颜色选择器内容的 Twitter Bootstrap Popover.js 丢失了附加的事件
Google Calendar API,如何添加带有附加新生成的google meet的事件?