当底层Viewmodel指示它应该在View触发器上有一个WPF EventTrigger时该怎么办?

时间:2009-09-14 22:22:43

标签: wpf events mvvm eventtrigger

以下是该方案:

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

<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>

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

public event EventHandler ActivateGlow;

并且在MVVM中非常正常,我为UnitViewModel提供了以下DataTemplate:

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

ulitmate问题是,如何设置某些内容以便viewmodel可以触发OnActivateGlow事件?

4 个答案:

答案 0 :(得分:11)

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

除了下载和安装SDK之外。获取表达式混合样本库的副本(您需要从以下链接单击“下载”): Expression Blend samples

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

混合SDK已经(我可以告诉)另一个难题 - 它已经包含一个允许你控制故事板的动作。此操作的名称是“ControlStoryboardAction”。

你应该得到一些看起来像这样的xaml:

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

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

以下是使用的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"

原始帖子,编辑前:

建议您研究Expression Blend Behaviors:

information

Blend SDK

video on behaviors

答案 1 :(得分:6)

您还可以在viewmodel上放置一个布尔值的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>  

答案 2 :(得分:0)

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

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

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

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

答案 3 :(得分:0)

我发现解决此问题的一种方法是在包含上述控件的DataTemplate上使用数据触发器......但这可能不是最好的方法。我仍然愿意接受更好的想法。