【问题标题】:How can I Have a WPF EventTrigger on a View trigger when the underlying Viewmodel dictates it should?当底层 Viewmodel 要求它应该时,如何在 View 触发器上拥有 WPF EventTrigger?
【发布时间】:2010-11-28 07:03:58
【问题描述】:

这是场景:

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

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

最重要的问题是,我怎样才能设置一些东西以便视图模型可以触发 OnActivateGlow 事件?

【问题讨论】:

    标签: wpf events mvvm eventtrigger


    【解决方案1】:

    您还可以在您的视图模型上放置一个布尔 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】:

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

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

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

      blend SDK 已经拥有(据我所知)难题的另一部分 - 它已经包含一个允许您控制情节提要的动作。此操作的名称是“ControlStoryboardAction”。

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

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

      将“YourEvent”替换为您在视图模型上定义的事件的名称,并将“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

      【讨论】:

      • 不确定这是否相关,据我所知,这都是与视图元素的视图绑定,它并没有真正反映在视图模型上。
      • 好吧..据我了解,您的问题围绕着让视图模型触发视图上的某些操作?你可以用混合行为来做这种事情。我不确定您是否会按照自己的方式对其进行建模 - 使用事件。但是你可以做一些事情,比如在你的视图模型上引发一个事件,在视图上拦截它,然后执行一个动作来响应这个事件。因此,在这种情况下,您将在 VM 上引发“requestglow”事件,在您的视图中拦截它,然后执行 beginstoryboard 操作。行为都是关于在没有代码隐藏的情况下启用 VM 和视图之间的交互
      • 这是一个视频,他们演示了混合行为的一些功能:channel9.msdn.com/shows/toolshed/… BTW,我想说,如果你使用的是 MVVM,你真的应该看看行为,即使您最终没有将它用于您当前的需求。这对 MVVM 来说意义重大!
      • 好的,我已经稍微了解了一些行为,将行为与 MVVM 触发的 CLR 事件联系起来的最佳方法是什么?
      • firoso,看看这个页面:expressionblend.codeplex.com 它包含一个混合行为库。它有一个名为“DataEventTrigger”的触发器,它允许您在绑定到数据上下文的对象上发生事件时触发操作。
      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        我相信您必须绑定到 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));
            }
        }
        

        【讨论】:

        • 好吧,这回答了我一半的问题,现在我如何让视图模型触发 ActivateGlow?
        • 添加 RoutedEvent 和 RaiseEvent,需要 UnitView 从 WPF 控件继承。问题要求 ViewModel,而不是控件。
        猜你喜欢
        • 1970-01-01
        • 2012-09-05
        • 2011-02-19
        • 1970-01-01
        • 2010-12-18
        • 2013-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多