使用EventTrigger引发附加事件
本文关键字:事件 EventTrigger 使用 | 更新日期: 2023-09-27 18:25:03
我有一个类MyAttachedEventClassAquarium
,它定义了一个从MSDN文档中获取的自定义附件。我有一个Window
,它在XAML中使用EventTrigger
来挂接要在Window
的视图模型上处理的事件。视图模型被声明为本地资源。
<Window.Resources>
<local:WinVM x:Key="myWinVM" />
</Window.Resources>
<i:Interaction.Triggers>
<i:EventTrigger EventName="NeedsCleaning" SourceName="MyAttachedEventClassAquarium">
<ei:CallMethodAction MethodName="MyCustomEventWasRaised" TargetObject="{StaticResource myWinVM}" />
</i:EventTrigger>
</i:Interaction.Triggers>
我使用窗口自己的RaiseEvent从按钮按下处理程序引发附加事件:
private void button1_Click(object sender, RoutedEventArgs e)
{
((Window1)((Grid)((Button)sender).Parent).Parent).RaiseEvent(new RoutedEventArgs(MyAttachedEventClassAquarium.NeedsCleaningEvent));
}
为什么不叫我的管理员?
提前谢谢。
B。
(已编辑)
这种挂钩事件以供ViewModel处理的方法看起来不太可能维护。要解决此问题,最好使用Snoop实用程序将视觉树和逻辑树分开,以确保您正在投射的对象(所有这些对象都实现RaiseEvent方法)实际上是您想要的对象。
您可能还需要将SourceName参数定义为Window上的资源。
这些只是猜测,它们描述了一种与MVVM模式所要求的非常不同的消息传递方法。与其像那样挖掘逻辑树(这是一种非常脆弱的方法),不如使用下面和其他地方的文档化和已验证的模式:访问Window
的DataContext
并直接调用VM方法。或者,在ViewModel类中实现ICommand
并将命令绑定到它
第一种方法打破了MVVM最纯粹的方法,但它会起作用。
private void button1_Click(object sender, RoutedEventArgs e)
{
var VM = this.DataContext As WinVM;
if (VM != null)
{
VM.MyCustomEventWasRaised();
}
}
另一种方法是在ViewModel类上实现ICommand
,并在View中配置Button
以使用以下命令:
<Button x:Name="Button1" Command="{Binding NeedsCleaning}" />
在大多数情况下,后者将消除对任何XAML代码隐藏代码的需要。
在我看来问题出在SourceName
上——它需要一个实例,而不是类名?如果我将事件源添加到视觉树中作为"aquary",并将"SourceName"更改为"aquarm",则会触发该操作:
<Window>
<Window.Resources>
<local:WinVM x:Key="myWinVM" />
</Window.Resources>
<i:Interaction.Triggers>
<i:EventTrigger EventName="NeedsCleaning" SourceName="aquarium">
<ei:CallMethodAction MethodName="MyCustomEventWasRaised" TargetObject="{StaticResource myWinVM}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<StackPanel>
<my:MyAttachedEventClassAquarium x:Name="aquarium" />
<Button x:Name="button" Click="button1_Click" Content="Raise Event" />
</StackPanel>
</Window>
private void button1_Click(object sender, RoutedEventArgs e)
{
aquarium.RaiseEvent(new RoutedEventArgs(MyAttachedEventClassAquarium.NeedsCleaningEvent));
}
只是补充:如果我都在水族馆对象上引发事件,并且也使用与EventTrigger的SourceName
相同的水族馆对象,则上述方法似乎仅适用于。这似乎与System.Windows.Interactivity.EventTrigger类有关(bug?),因为当我使用DependencyObject.Triggers.EventTrigger类时,事件会像您预期的那样冒泡。