Как я могу иметь WPF EventTrigger на триггере View, когда базовая Viewmodel требует этого?

StackOverflow https://stackoverflow.com/questions/1424202

  •  07-07-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

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

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

Эта библиотека содержит встроенный триггер 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

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

Другие советы

Вы также можете добавить логическое свойство 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>  

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top