How to play Storyboard in ViewModel?

前端 未结 5 958
萌比男神i
萌比男神i 2021-01-15 12:04

I defiend a storyborad in View

  
            

        
相关标签:
5条回答
  • 2021-01-15 12:19

    You could call the Storyboard from a code-behind as long as you assigned it x:Name. But then, you'd need to implement a button_click event handler, not a command for the ViewModel.

    If you're using MVVM then you should really abide by the principle that the ViewModel should not "know" about specifics of the View.

    0 讨论(0)
  • 2021-01-15 12:21

    You should not access Storyboard from your ViewModel. It defeats the purpose of MVVM altogether.

    You can apply storyboard on Button.LostMouseCapture event which gets raised after your command gets called on Click event -

    <Button x:Name="AddUserButton"  Content="اضافه">
       <i:Interaction.Triggers>
          <i:EventTrigger EventName="Click">
            <cmd:EventToCommand Command="{Binding AddUsers}"/>
          </i:EventTrigger>
       </i:Interaction.Triggers>
       <Button.Triggers>
           <EventTrigger RoutedEvent="Button.LostMouseCapture">
                <BeginStoryboard Storyboard="{StaticResource ExpandAdd}">
           </EventTrigger>
       </Button.Triggers>
    </Button>
    
    0 讨论(0)
  • 2021-01-15 12:21

    For UWP: You can define your storyboard in VisualStates and run it by changing property in ViewModel. If you change IsRefreshWorking property to true animation begins.

    Define VisualState, using IsTrueTrigger:

        <VisualStateManager.VisualStateGroups>
           <VisualStateGroup x:Name="RefreshProgressVisualStates">
              <VisualState x:Name="NotWorkingVisualState" />
              <VisualState x:Name="WorkingVisualState">
                 <Storyboard  AutoReverse="False" RepeatBehavior="Forever">
                    <DoubleAnimation Duration="0:0:1" To="360" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="RefreshIcon" />
                 </Storyboard>
                 <VisualState.StateTriggers>
                    <StateTrigger  IsActive="{x:Bind ViewModel.IsRefreshWorking, Mode=OneWay}" />
                 </VisualState.StateTriggers>
              </VisualState>
           </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    

    AppBarButton with animation:

    <AppBarButton>
      <AppBarButton.Icon>
         <SymbolIcon x:Name="RefreshIcon"  Symbol="Refresh" RenderTransformOrigin="0.5,0.5" >
             <SymbolIcon.RenderTransform>
                <CompositeTransform/>
             </SymbolIcon.RenderTransform>
          </SymbolIcon>
      </AppBarButton.Icon>
    </AppBarButton>
    
    0 讨论(0)
  • 2021-01-15 12:29

    Please don't trigger the storyboard from the viewmodel. If you do then there is no point having a viewmodel.

    Implement any code for the relay command in the code behind of the view, then if needed you can call through to the viewmodel to do anything that is viewmodel specific. When you reference the storyboard from the code behind of the view you can just refer to it by name.

    0 讨论(0)
  • 2021-01-15 12:31

    Actually, this is relatively easy to do by using a DataTrigger that is bound to a property in the ViewModel, thus triggering the Storyboard from the MV while still maintaining separation of concerns. Here's a very brief example where a Storyboard grows an image in size in response to a bool in the VM changing to True.

    <Image
        Grid.Row="0" 
        x:Name="LockImage"
        Source="/StoryboardManagerExample;component/Resources/LockedPadlock.png" 
        Width="50"
        RenderTransformOrigin="0.5,0.5">
    
        <Image.RenderTransform>
            <TransformGroup>
                <ScaleTransform x:Name="ptScale" ScaleX="1" ScaleY="1"/>
                <SkewTransform />
                <RotateTransform />
                <TranslateTransform />
            </TransformGroup>
        </Image.RenderTransform>
    
        <Image.Style>
            <Style>
                <Style.Triggers>
                    <DataTrigger
                        Binding="{Binding RunStoryboard}" Value="True">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation
                                    Storyboard.TargetProperty="Width"
                                    From="50"
                                    To="100"
                                    Duration="0:0:1"
                                    RepeatBehavior="1x"
                                    AutoReverse="True"
                                    />
    
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.EnterActions>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Image.Style>
    </Image>
    
    0 讨论(0)
提交回复
热议问题