Как начать StoryBoard из ViewModel? - PullRequest
       7

Как начать StoryBoard из ViewModel?

2 голосов
/ 15 октября 2011

Я использую элементы управления Telerik в моем примере.

<telerik:RadPanelBarItem Collapsed="RadPanelBarItem_Collapsed"
                                     DropPosition="Inside"
                                     Header="Searching for Clients"
                                     IsExpanded="false"
                                     IsTabStop="True"
                                     TabNavigation="Once">

     <i:Interaction.Triggers>
         <i:EventTrigger EventName="Expanded">
             <i:InvokeCommandAction Command="{Binding ExpandedComand}" />
         </i:EventTrigger>
     </i:Interaction.Triggers>
</telerik:RadPanelBarItem>

Я хотел бы запускать код в ViewModel всякий раз, когда вызывается событие Expanded.Пока все хорошо, но мне также нужно запустить анимацию после ее расширения.Но это невозможно из ViewModel, но оно должно работать в представлении:

ArrowStoryboard.Begin();

Так как мне это сделать?

ОБНОВЛЕНИЕ:

Позвольте мне остановиться подробнее, так как кажется, это вызвало некоторую путаницуМне не нужно выполнять связанную анимацию вида из ViewModel.Но я должен выполнить две вещи при расширении события.1) Начните анимацию и 2) запустите набор кода в viewModel.

Единственный известный мне способ, но он не очень хорош, так как он рекламирует код для выделенного кода, заключается в следующем: приведение DataContext кViewModel и запустите соответствующий метод на ViewModel сразу после начала анимации.

Спасибо,

Ответы [ 2 ]

2 голосов
/ 15 октября 2011

Почему бы не присоединить другое поведение ControlStoryboardAction в сторону вашего InvokeCommandAction?

xmlns:eim="clr-namespace:Microsoft.Expression.Interactivity.Media;assembly=Microsoft.Expression.Interactions" 

 <i:Interaction.Triggers> 
     <i:EventTrigger EventName="Expanded"> 
         <i:InvokeCommandAction Command="{Binding ExpandedComand}" /> 
         <eim:ControlStoryboardAction Storyboard="{StaticResource YourStoryBoard}"/>
     </i:EventTrigger> 
 </i:Interaction.Triggers> 

UPDATE

На самом деле не так уж много работы, чтобы делать подобные анимации внутри стиля, используя Blend.

Что я сделал здесь, так это то, что я использовал Blend для генерации стиля RadPanelBarItem по умолчанию, затем в визуальном состоянии Expand я создал анимацию, которая вылетает из стрелки и заставляет ее работать вечно.

Это не совсем та анимация, которую вы хотите (стрелка идет вверх, а не вправо), но она может дать вам некоторые идеи. Надеюсь это поможет. :)

Просто примените имя стиля AnimatedRadPanelBarItemStyle.

    <LinearGradientBrush x:Key="ControlItem_Background_Normal" EndPoint="0.5,1" StartPoint="0.5,0">
        <GradientStop Color="White"/>
        <GradientStop Color="Gainsboro" Offset="0.43"/>
        <GradientStop Color="#FFADADAD" Offset="0.44"/>
        <GradientStop Color="#FFD4D4D4" Offset="1"/>
    </LinearGradientBrush>
    <SolidColorBrush x:Key="ControlItem_OuterBorder_Normal" Color="#FF848484"/>
    <SolidColorBrush x:Key="ControlForeground_Normal" Color="#FF000000"/>
    <SolidColorBrush x:Key="ControlItem_InnerBorder_Normal" Color="#FFFFFFFF"/>
    <SolidColorBrush x:Key="ControlItem_OuterBorder_MouseOver" Color="#FFFFC92B"/>
    <SolidColorBrush x:Key="ControlItem_InnerBorder_MouseOver" Color="#FFFFFFFF"/>
    <LinearGradientBrush x:Key="ControlItem_Background_MouseOver" EndPoint="0.5,1" StartPoint="0.5,0">
        <GradientStop Color="#FFFFFBA3" Offset="1"/>
        <GradientStop Color="#FFFFFBDA" Offset="0"/>
        <GradientStop Color="#FFFFD25A" Offset="0.43"/>
        <GradientStop Color="#FFFEEBAE" Offset="0.42"/>
    </LinearGradientBrush>
    <LinearGradientBrush x:Key="ControlItem_OuterBorder_Selected" EndPoint="0.5,1" StartPoint="0.5,0">
        <GradientStop Color="#FF282828"/>
        <GradientStop Color="#FF5F5F5F" Offset="1"/>
    </LinearGradientBrush>
    <LinearGradientBrush x:Key="ControlItem_InnerBorder_Selected" EndPoint="0.5,1" StartPoint="0.5,0">
        <GradientStop Color="#FFB69A78"/>
        <GradientStop Color="#FFFFE17A" Offset="0.126"/>
    </LinearGradientBrush>
    <LinearGradientBrush x:Key="ControlItem_Background_Selected" EndPoint="0.5,1" StartPoint="0.5,0">
        <GradientStop Color="#FFFFD74E" Offset="0.996"/>
        <GradientStop Color="#FFFFDCAB" Offset="0.17"/>
        <GradientStop Color="#FFFFB062" Offset="0.57"/>
        <GradientStop Color="#FFFFD18F" Offset="0.56"/>
        <GradientStop Color="#FFFFBA74"/>
    </LinearGradientBrush>
    <SolidColorBrush x:Key="ControlOuterBorder_Disabled" Color="#FF989898"/>
    <SolidColorBrush x:Key="ControlInnerBorder_Disabled" Color="Transparent"/>
    <SolidColorBrush x:Key="ControlBackground_Disabled" Color="#FFE0E0E0"/>
    <SolidColorBrush x:Key="ControlElement_Normal" Color="#FF000000"/>
    <SolidColorBrush x:Key="FocusBrushBlack" Color="#FF000000"/>
    <ControlTemplate x:Key="PanelBarItemTopLevelTemplate" TargetType="telerik:RadPanelBarItem">
        <Grid x:Name="RootElement">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="CommonStates">
                    <VisualState x:Name="Normal"/>
                    <VisualState x:Name="Disabled">
                        <Storyboard>
                            <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="NormalVisual"/>
                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisabledVisual"/>
                            <DoubleAnimation Duration="0" To="0.5" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Header"/>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="arrow">
                                <DiscreteObjectKeyFrame KeyTime="0">
                                    <DiscreteObjectKeyFrame.Value>
                                        <Visibility>Collapsed</Visibility>
                                    </DiscreteObjectKeyFrame.Value>
                                </DiscreteObjectKeyFrame>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="MouseOver">
                        <Storyboard>
                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="MouseOverVisual"/>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="MouseOut"/>
                </VisualStateGroup>
                <VisualStateGroup x:Name="SelectionStates">
                    <VisualState x:Name="Unselected"/>
                    <VisualState x:Name="Selected">
                        <Storyboard>
                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="SelectVisual"/>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
                <VisualStateGroup x:Name="ExpandStates">
                    <VisualState x:Name="Expanded">
                        <Storyboard RepeatBehavior="Forever">
                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ItemsContainer">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                            </ObjectAnimationUsingKeyFrames>
                            <DoubleAnimation Duration="0:0:0.2" From="0.0" To="1.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ItemsContainer"/>
                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="arrow">
                                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="-6"/>
                                <EasingDoubleKeyFrame KeyTime="0:0:1.2" Value="0"/>
                                <EasingDoubleKeyFrame KeyTime="0:0:1.4" Value="0"/>
                            </DoubleAnimationUsingKeyFrames>
                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="arrow">
                                <EasingDoubleKeyFrame KeyTime="0" Value="180"/>
                                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="180"/>
                                <EasingDoubleKeyFrame KeyTime="0:0:1.2" Value="180"/>
                                <EasingDoubleKeyFrame KeyTime="0:0:1.4" Value="180"/>
                            </DoubleAnimationUsingKeyFrames>
                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="arrow">
                                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
                                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/>
                                <EasingDoubleKeyFrame KeyTime="0:0:1.2" Value="0"/>
                                <EasingDoubleKeyFrame KeyTime="0:0:1.4" Value="1"/>
                            </DoubleAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="Collapsed"/>
                </VisualStateGroup>
                <VisualStateGroup x:Name="FocusStates">
                    <VisualState x:Name="Focused">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="FocusVisual">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="Unfocused">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="FocusVisual">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <Grid x:Name="HeaderRow">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <Border x:Name="NormalVisual" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Grid.ColumnSpan="5">
                    <Border BorderBrush="{StaticResource ControlItem_InnerBorder_Normal}" BorderThickness="1" Background="{TemplateBinding Background}"/>
                </Border>
                <Border x:Name="MouseOverVisual" BorderBrush="{StaticResource ControlItem_OuterBorder_MouseOver}" BorderThickness="1" Grid.ColumnSpan="5" Opacity="0">
                    <Border BorderBrush="{StaticResource ControlItem_InnerBorder_MouseOver}" BorderThickness="1" Background="{StaticResource ControlItem_Background_MouseOver}"/>
                </Border>
                <Border x:Name="SelectVisual" BorderBrush="{StaticResource ControlItem_OuterBorder_Selected}" BorderThickness="1" Grid.ColumnSpan="5" Opacity="0">
                    <Border BorderBrush="{StaticResource ControlItem_InnerBorder_Selected}" BorderThickness="1" Background="{StaticResource ControlItem_Background_Selected}"/>
                </Border>
                <Border x:Name="DisabledVisual" BorderBrush="{StaticResource ControlOuterBorder_Disabled}" BorderThickness="1" Grid.ColumnSpan="5" Opacity="0">
                    <Border BorderBrush="{StaticResource ControlInnerBorder_Disabled}" BorderThickness="1" Background="{StaticResource ControlBackground_Disabled}"/>
                </Border>
                <Path x:Name="arrow" Grid.Column="5" Data="M 1,1.5 L 4.5,5 L 8,1.5" HorizontalAlignment="Right" Margin="7 0" Opacity="1" RenderTransformOrigin="0.5 0.5" Stretch="None" Stroke="{StaticResource ControlElement_Normal}" StrokeThickness="2" VerticalAlignment="Center">
                    <Path.RenderTransform>
                        <CompositeTransform Rotation="0"/>
                    </Path.RenderTransform>
                </Path>
                <ContentPresenter x:Name="Header" Grid.ColumnSpan="4" ContentTemplate="{TemplateBinding HeaderTemplate}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                <Rectangle x:Name="FocusVisual" Grid.ColumnSpan="5" Grid.Column="0" IsHitTestVisible="False" Stroke="{StaticResource FocusBrushBlack}" StrokeThickness="1" StrokeDashArray="1 2" Visibility="Collapsed"/>
            </Grid>
            <Grid x:Name="ItemsContainer" Grid.Row="1" Visibility="Collapsed">
                <telerik:LayoutTransformControl x:Name="transformationRoot">
                    <ItemsPresenter/>
                </telerik:LayoutTransformControl>
            </Grid>
        </Grid>
    </ControlTemplate>
    <SolidColorBrush x:Key="ControlSubItem_OuterBorder_MouseOver" Color="#FFFFC92B"/>
    <Thickness x:Key="ControlSubItem_OuterBorderThickness">1</Thickness>
    <SolidColorBrush x:Key="ControlSubItem_InnerBorder_MouseOver" Color="#FFFFFFFF"/>
    <Thickness x:Key="ControlSubItem_InnerBorderThickness">1</Thickness>
    <LinearGradientBrush x:Key="ControlSubItem_Background_MouseOver" EndPoint="0.5,1" StartPoint="0.5,0">
        <GradientStop Color="#FFFFFBA3" Offset="1"/>
        <GradientStop Color="#FFFFFBDA" Offset="0"/>
    </LinearGradientBrush>
    <CornerRadius x:Key="ControlSubItem_InnerCornerRadius">0</CornerRadius>
    <CornerRadius x:Key="ControlSubItem_OuterCornerRadius">1</CornerRadius>
    <SolidColorBrush x:Key="ControlSubItem_OuterBorder_Selected" Color="#FFFFC92B"/>
    <SolidColorBrush x:Key="ControlSubItem_InnerBorder_Selected" Color="#FFFFFFFF"/>
    <LinearGradientBrush x:Key="ControlSubItem_Background_Selected" EndPoint="0.5,1" StartPoint="0.5,0">
        <GradientStop Color="#FFFCE79F" Offset="1"/>
        <GradientStop Color="#FFFDD3A8"/>
    </LinearGradientBrush>
    <ControlTemplate x:Key="PanelBarItemSecondLevelTemplate" TargetType="telerik:RadPanelBarItem">
        <Grid x:Name="RootElement">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="CommonStates">
                    <VisualState x:Name="Normal"/>
                    <VisualState x:Name="Disabled">
                        <Storyboard>
                            <DoubleAnimation Duration="0" To="1.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisabledVisual"/>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="MouseOver">
                        <Storyboard>
                            <DoubleAnimation Duration="0:0:0.2" To="1.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="MouseOverVisual"/>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="MouseOut">
                        <Storyboard>
                            <DoubleAnimation Duration="0:0:0.2" To="0.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="MouseOverVisual"/>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
                <VisualStateGroup x:Name="SelectionStates">
                    <VisualState x:Name="Unselected"/>
                    <VisualState x:Name="Selected">
                        <Storyboard>
                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="SelectionVisual"/>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
                <VisualStateGroup x:Name="ExpandStates">
                    <VisualState x:Name="Expanded">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ItemsContainer">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                            </ObjectAnimationUsingKeyFrames>
                            <DoubleAnimation Duration="0:0:0.2" From="0.0" To="1.0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ItemsContainer"/>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="Collapsed"/>
                </VisualStateGroup>
                <VisualStateGroup x:Name="FocusStates">
                    <VisualState x:Name="Focused">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="FocusVisual">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="Unfocused">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetProperty="Visibility" Storyboard.TargetName="FocusVisual">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <Grid x:Name="HeaderRow" Background="Transparent">
                <Border x:Name="MouseOverVisual" BorderBrush="{StaticResource ControlSubItem_OuterBorder_MouseOver}" BorderThickness="{StaticResource ControlSubItem_OuterBorderThickness}" CornerRadius="{StaticResource ControlSubItem_OuterCornerRadius}" Opacity="0">
                    <Border BorderBrush="{StaticResource ControlSubItem_InnerBorder_MouseOver}" BorderThickness="{StaticResource ControlSubItem_InnerBorderThickness}" Background="{StaticResource ControlSubItem_Background_MouseOver}" CornerRadius="{StaticResource ControlSubItem_InnerCornerRadius}"/>
                </Border>
                <Border x:Name="SelectionVisual" BorderBrush="{StaticResource ControlSubItem_OuterBorder_Selected}" BorderThickness="{StaticResource ControlSubItem_OuterBorderThickness}" CornerRadius="{StaticResource ControlSubItem_OuterCornerRadius}" Opacity="0">
                    <Border BorderBrush="{StaticResource ControlSubItem_InnerBorder_Selected}" BorderThickness="{StaticResource ControlSubItem_InnerBorderThickness}" Background="{StaticResource ControlSubItem_Background_Selected}" CornerRadius="{StaticResource ControlSubItem_InnerCornerRadius}"/>
                </Border>
                <Border x:Name="DisabledVisual" BorderBrush="{StaticResource ControlOuterBorder_Disabled}" BorderThickness="{StaticResource ControlSubItem_OuterBorderThickness}" CornerRadius="{StaticResource ControlSubItem_OuterCornerRadius}" Opacity="0">
                    <Border BorderBrush="{StaticResource ControlInnerBorder_Disabled}" BorderThickness="{StaticResource ControlSubItem_InnerBorderThickness}" Background="{StaticResource ControlBackground_Disabled}" CornerRadius="{StaticResource ControlSubItem_InnerCornerRadius}"/>
                </Border>
                <ContentPresenter x:Name="Header" ContentTemplate="{TemplateBinding HeaderTemplate}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                <Rectangle x:Name="FocusVisual" IsHitTestVisible="False" RadiusY="2" RadiusX="2" Stroke="{StaticResource FocusBrushBlack}" StrokeThickness="1" StrokeDashArray="1 2" Visibility="Collapsed"/>
            </Grid>
            <Grid x:Name="ItemsContainer" Grid.Row="1" Visibility="Collapsed">
                <ItemsPresenter/>
            </Grid>
        </Grid>
    </ControlTemplate>
    <Style x:Key="AnimatedRadPanelBarItemStyle" TargetType="telerik:RadPanelBarItem">
        <Setter Property="Background" Value="{StaticResource ControlItem_Background_Normal}"/>
        <Setter Property="BorderBrush" Value="{StaticResource ControlItem_OuterBorder_Normal}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Foreground" Value="{StaticResource ControlForeground_Normal}"/>
        <Setter Property="TabNavigation" Value="Once"/>
        <Setter Property="IsTabStop" Value="True"/>
        <Setter Property="Template" Value="{StaticResource PanelBarItemTopLevelTemplate}"/>
        <Setter Property="Padding" Value="3"/>
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        <Setter Property="VerticalContentAlignment" Value="Stretch"/>
        <Setter Property="ChildItemsTemplate" Value="{StaticResource PanelBarItemSecondLevelTemplate}"/>
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <telerik:PanelBarPanel/>
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
    </Style>
2 голосов
/ 15 октября 2011

Это плохая идея - вызывать действие, специфичное для представления, из ViewModel, поскольку раскадровка не имеет ничего общего с моделью представления.Есть два способа достичь того, что вы хотите сделать.

  1. Вы можете внедрить View в ViewModel, но мне действительно не нравится эта идея, поскольку MVVM пытается сделать View и ViewModel менее связанными.
  2. Используйте службу сообщений для отправки и получения данных между View и ViewModel таким образом, чтобы они не знали друг друга.Я использую MVVMLight в своем проекте и использую его класс Messenger.MVVMLight очень прост в использовании.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...