是否可以使用带有附加事件的 Microsoft.Xaml.Behaviors.EventTrigger 来调用命令?
Is it possible to use invoke a command using an Microsoft.Xaml.Behaviors.EventTrigger with attached events?
我正在尝试使用附加事件来调用 ICommand
。
我正在使用 Microsoft.Toolkit.Mvvm
NuGet 包,以及 Microsoft.Xaml.Behaviors.Wpf
Nuget 包。
通过定义 <EventTrigger />
并将 RoutedEvent
设置为附加事件的名称,我已成功使用 <FOO.Triggers />
中的 <BeginStoryBoardAction />
启动故事板有问题。
但是,据我所知,没有办法使用 <EventTrigger />
中提供的任何内容来调用 ICommand
。我的意思是,我无法在 <EventTriggers.Actions />
块(类似于 <Behaviors.InvokeCommandAction />
)的主体中使用任何东西,这将导致 ICommand
被调用。
根据Minimal, Complete and Verifiable example,为了演示我正在努力实现的目标,您可以参考GitHub - https://github.com/AbbottWC/MCVE_AttachedEventFailure.
上的项目
或
打开Visual Studio。创建 WPF 应用程序(针对 .Net Core 3.1)
工具 -> NuGet 包管理器 -> 管理此解决方案的包
添加 Microsoft.Toolkit.Mvvm(对于 RelayCommand
class)和 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>
那么重申一下我的问题,我在这里尝试实现的目标是否可行?以这种方式使用附加事件是不可能的吗?
谢谢。
据我了解,EventTrigger
只能监听源对象“拥有”的事件。因此,要回答您的问题,使用 EventTrigger
class.
是不可能的
如果您查看 source,当您传递 Mouse.MouseEnter
时,它会尝试从目标类型中获取该事件。此外,由于您没有指定目标,它默认为 AssociatedObject
,在您的情况下为 Window
。
Type targetType = obj.GetType();
EventInfo eventInfo = targetType.GetEvent(eventName);
现在我发现的问题是,如果它找不到事件,它只会在源对象不为空时抛出异常,而在你的情况下你没有指定一个,所以它会默默地失败。不知道设计师为什么要这样做。
现在,我确实找到了这个博客 post,它准确地描述了如何解决这个问题:
https://sergecalderara.wordpress.com/2012/08/23/how-to-attached-an-mvvm-eventtocommand-to-an-attached-event/
基本上,您继承自 EventTriggerBase<T>
,在 OnAttached
方法中,您需要在 AssociatedObject
上调用 AddHandler
来添加事件。
我正在尝试使用附加事件来调用 ICommand
。
我正在使用 Microsoft.Toolkit.Mvvm
NuGet 包,以及 Microsoft.Xaml.Behaviors.Wpf
Nuget 包。
通过定义 <EventTrigger />
并将 RoutedEvent
设置为附加事件的名称,我已成功使用 <FOO.Triggers />
中的 <BeginStoryBoardAction />
启动故事板有问题。
但是,据我所知,没有办法使用 <EventTrigger />
中提供的任何内容来调用 ICommand
。我的意思是,我无法在 <EventTriggers.Actions />
块(类似于 <Behaviors.InvokeCommandAction />
)的主体中使用任何东西,这将导致 ICommand
被调用。
根据Minimal, Complete and Verifiable example,为了演示我正在努力实现的目标,您可以参考GitHub - https://github.com/AbbottWC/MCVE_AttachedEventFailure.
上的项目或
打开Visual Studio。创建 WPF 应用程序(针对 .Net Core 3.1)
工具 -> NuGet 包管理器 -> 管理此解决方案的包
添加 Microsoft.Toolkit.Mvvm(对于
RelayCommand
class)和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>
那么重申一下我的问题,我在这里尝试实现的目标是否可行?以这种方式使用附加事件是不可能的吗?
谢谢。
据我了解,EventTrigger
只能监听源对象“拥有”的事件。因此,要回答您的问题,使用 EventTrigger
class.
如果您查看 source,当您传递 Mouse.MouseEnter
时,它会尝试从目标类型中获取该事件。此外,由于您没有指定目标,它默认为 AssociatedObject
,在您的情况下为 Window
。
Type targetType = obj.GetType();
EventInfo eventInfo = targetType.GetEvent(eventName);
现在我发现的问题是,如果它找不到事件,它只会在源对象不为空时抛出异常,而在你的情况下你没有指定一个,所以它会默默地失败。不知道设计师为什么要这样做。
现在,我确实找到了这个博客 post,它准确地描述了如何解决这个问题: https://sergecalderara.wordpress.com/2012/08/23/how-to-attached-an-mvvm-eventtocommand-to-an-attached-event/
基本上,您继承自 EventTriggerBase<T>
,在 OnAttached
方法中,您需要在 AssociatedObject
上调用 AddHandler
来添加事件。