当底层 Viewmodel 指示它应该时,如何在 View 触发器上设置 WPF EventTrigger?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1424202/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:00:12  来源:igfitidea点击:

How can I Have a WPF EventTrigger on a View trigger when the underlying Viewmodel dictates it should?

wpfeventsmvvmeventtrigger

提问by Firoso

Here's the scenario:

这是场景:

I have the following user control, the idea is that it's view model should be able to signal to the view that it needs to "Activate the Glow", thereby playing the Storyboard.

我有以下用户控件,想法是它的视图模型应该能够向视图发出信号,它需要“激活发光”,从而播放故事板。

<UserControl x:Class="View.UnitView"  ... >
   ...
    <Storyboard x:Key="ActivateGlow">
       ...
    </Storyboard>
    ...
    <!-- INVALID BINDING! Not Dependancy Object-->
    <EventTrigger RoutedEvent="{Binding OnActivateGlow}"> 
       <BeginStoryboard Storyboard="{StaticResource ActivateGlow}"/>
    </EventTrigger>
</UserControl>

in the codebehind for UnitView, I have:

在 UnitView 的代码隐藏中,我有:

public event EventHandler ActivateGlow;

and as is pretty normal in MVVM, I have the following DataTemplate for UnitViewModel:

在 MVVM 中很正常,我有以下用于 UnitViewModel 的 DataTemplate:

<DataTemplate DataType="{x:Type vm:UnitViewModel}">
    <vw:UnitView d:DesignWidth="150" d:DesignHeight="100" />
</DataTemplate>

The ulitmate question is, how can I set up something so that the viewmodel can fire the OnActivateGlow event?

最终的问题是,我如何设置一些东西以便视图模型可以触发 OnActivateGlow 事件?

采纳答案by Phil

Update: Firoso, as mentioned in the comments you should be able to (I think - i.e. untested) be able to use the blend behavior components to cover your requirement.

更新:Firoso,如评论中所述,您应该能够(我认为 - 即未经测试)能够使用混合行为组件来满足您的要求。

In addition to downloading and installing the SDK. Get a copy of the expression blend samples library (you'll need to click on Downloads from the following link): Expression Blend samples

除了下载和安装SDK。获取表达式混合示例库的副本(您需要单击以下链接中的下载): Expression Blend 示例

This library contains a prebuilt trigger called 'DataEventTrigger' which you can use to trigger actions in response to an event declared on your viewmodel.

该库包含一个名为“DataEventTrigger”的预构建触发器,您可以使用它来触发操作以响应在您的视图模型上声明的事件。

The blend SDK already has (from what I can tell) the other piece of the puzzle - it already includes an action which allows you to control storyboards. The name of this action is 'ControlStoryboardAction'.

Blend SDK 已经有了(据我所知)难题的另一部分——它已经包含一个允许您控制故事板的动作。此操作的名称是“ControlStoryboardAction”。

You should end up with some xaml which looks like this:

您应该最终得到一些 xaml,如下所示:

    <i:Interaction.Triggers>
        <samples:DataEventTrigger EventName="YourEvent">
            <im:ControlStoryboardAction Storyboard="{StaticResource Storyboard1}" 
                   ControlStoryboardOption="Play"/>
        </samples:DataEventTrigger>
    </i:Interaction.Triggers>

Replace 'YourEvent' with the name of the event you have defined on your viewmodel, and replace 'Storyboard1' with the name of your storyboard. Of course the names will have to match exactly.

将“YourEvent”替换为您在视图模型上定义的事件的名称,并将“Storyboard1”替换为您的故事板的名称。当然,名称必须完全匹配。

Here are the xaml namespace definitions used:

以下是使用的 xaml 命名空间定义:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
xmlns:im="clr-namespace:Microsoft.Expression.Interactivity.Media;assembly=Microsoft.Expression.Interactions"
xmlns:samples="clr-namespace:Expression.Samples.Interactivity;assembly=Expression.Samples.Interactivity"

Original post, before edit:

原帖,编辑前:

Suggest you look into Expression Blend Behaviors:

建议您查看 Expression Blend Behaviors:

information

信息

Blend SDK

混合 SDK

video on behaviors

行为视频

回答by kenwarner

You can also put a boolean IsGlowing property on your viewmodel and use datatriggers in your style

您还可以在您的视图模型上放置一个布尔值 IsGlowing 属性并在您的样式中使用数据触发器

<Rectangle.Style>  
    <Style TargetType="{x:Type Rectangle}">  
        <Style.Triggers>  
            <DataTrigger Binding="{Binding Path=IsGlowing}" Value="True">  
                <DataTrigger.EnterActions>  
                    <BeginStoryboard>  
                        <Storyboard>  
                            ...  
                        </Storyboard>  
                    </BeginStoryboard>  
                </DataTrigger.EnterActions>  
            </DataTrigger>  
        </Style.Triggers>  
    </Style>  
</Rectangle.Style>  

回答by Firoso

One way I found to resolve this is to use a data trigger on a DataTemplate that contains the above control... probably not the best way to do this however. I'm still open to better ideas.

我发现解决此问题的一种方法是在包含上述控件的 DataTemplate 上使用数据触发器……然而,这可能不是最好的方法。我仍然对更好的想法持开放态度。

回答by Drew Noakes

I believe you would have to bind to a RoutedEventinstance, not a CLR event.

我相信您必须绑定到一个RoutedEvent实例,而不是一个 CLR 事件。

I haven't tried it, but something like this should work:

我还没有尝试过,但这样的事情应该可行:

public class UnitView
{
    public static readonly RoutedEvent ActivateGlowEvent
        = EventManager.RegisterRoutedEvent(
              "ActivateGlow", RoutingStrategy.Bubble,
              typeof(RoutedEventHandler), typeof(UnitView)
          );

    public void RaiseActivateGlowEvent()
    {
        RaiseEvent(new RoutedEventArgs(ActivateGlowEvent));
    }
}