Как я могу иметь WPF EventTrigger на триггере View, когда базовая Viewmodel требует этого? - PullRequest
24 голосов
/ 15 сентября 2009

Вот сценарий:

У меня есть следующий пользовательский элемент управления, идея в том, что его модель представления должна иметь возможность сигнализировать представлению, что ей нужно «активировать свечение», тем самым играя на раскадровке.

<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, у меня есть следующий DataTemplate для UnitViewModel:

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

Главный вопрос: как я могу настроить что-то, чтобы модель представления могла запустить событие OnActivateGlow?

Ответы [ 4 ]

11 голосов
/ 04 января 2010

Обновление: Firoso, как упомянуто в комментариях, вы должны быть в состоянии (я думаю - то есть не проверено) иметь возможность использовать компоненты поведения смешивания для удовлетворения ваших требований.

В дополнение к загрузке и установке SDK. Получите копию библиотеки примеров выражений blend (вам нужно нажать на ссылку «Загрузки» по следующей ссылке): Образцы смеси Expression

Эта библиотека содержит предварительно созданный триггер DataEventTrigger, который вы можете использовать для запуска действий в ответ на событие, объявленное в вашей модели представления.

Смешанный 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

видео о поведении

6 голосов
/ 05 января 2010

Вы также можете добавить логическое свойство 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>  
0 голосов
/ 04 января 2010

Один способ, который я нашел, чтобы решить эту проблему, это использовать триггер данных на DataTemplate, который содержит вышеуказанный элемент управления ... однако, вероятно, это не лучший способ сделать это. Я все еще открыт для лучших идей.

0 голосов
/ 15 сентября 2009

Полагаю, вам нужно будет привязать экземпляр 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));
    }
}
...