当底层视图模型指示它应该时,如何在视图触发器上拥有 WPF EventTrigger?

发布于 2024-08-04 22:27:46 字数 873 浏览 10 评论 0原文

场景如下:

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

<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 事件?

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:

public event EventHandler ActivateGlow;

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

琉璃梦幻 2024-08-11 22:27:46

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

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

该库包含一个名为“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"

原始帖子,编辑前:

建议您研究表达式混合行为:

信息

Blend SDK

有关行为的视频

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.

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

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

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

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

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

Here are the xaml namespace definitions used:

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:

information

Blend SDK

video on behaviors

岁吢 2024-08-11 22:27:46

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

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

<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>  
-黛色若梦 2024-08-11 22:27:46

我相信您必须绑定到 RoatedEvent< /code>实例,不是 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));
    }
}

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

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));
    }
}
甜妞爱困 2024-08-11 22:27:46

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文