2015-06-12 2 views
2

Я создал шаблон управления для кнопки, содержащей сетку и элемент управления контентом. Я хочу сделать следующее: при нажатии кнопки масштаб кнопки должен оживить до 0,5 и когда кнопка покинет нажатое состояние, масштаб кнопки должен вернуться к 1.0.Animate ScaleTransform кнопки с помощью VisualStateManager

В моем текущем решении анимация для масштабирования = 0.5 работает хорошо, если кнопка нажата. Но как только я отпустить кнопку, анимация не масштабируется медленно назад в масштабе 1. Вместо ее незамедлительное в масштабе 1.

Моя реализация выглядит следующим образом:

<Style TargetType="Button" x:Name="MyButtonStyle"> 
     <Setter Property="Margin" Value="0"/> 
     <Setter Property="Padding" Value="0"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="Button"> 
        <Grid Background="{TemplateBinding Background}" x:Name="buttonLayoutRoot"> 
         <Grid.RenderTransform> 
          <ScaleTransform ScaleX="1" ScaleY="1"/> 
         </Grid.RenderTransform> 
         <VisualStateManager.VisualStateGroups> 
          <VisualStateGroup x:Name="CommonStates"> 
           <VisualStateGroup.Transitions> 
            <VisualTransition To="Pressed" GeneratedDuration="0:0:2.5"> 
             <Storyboard> 
              <DoubleAnimation 
              Storyboard.TargetName="buttonLayoutRoot" 
              Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleX)" 
              To="0.5" Duration="0:0:2.5"/> 
              <DoubleAnimation 
              Storyboard.TargetName="buttonLayoutRoot" 
              Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleY)" 
              To="0.5" Duration="0:0:2.5"/> 
             </Storyboard> 
            </VisualTransition> 
            <VisualTransition To="Normal" GeneratedDuration="0:0:2.5"> 
             <Storyboard> 
              <DoubleAnimation 
              Storyboard.TargetName="buttonLayoutRoot" 
              Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleX)" 
              To="1.0" Duration="0:0:2.5"/> 
              <DoubleAnimation 
              Storyboard.TargetName="buttonLayoutRoot" 
              Storyboard.TargetProperty="(Grid.RenderTransform).(ScaleTransform.ScaleY)" 
              To="1.0" Duration="0:0:2.5"/> 
             </Storyboard> 
            </VisualTransition> 
           </VisualStateGroup.Transitions> 
           <VisualState x:Name="Normal"/> 
           <VisualState x:Name="MouseOver" /> 
           <VisualState x:Name="Pressed"/> 
           <VisualState x:Name="Disabled"/> 
          </VisualStateGroup> 

         </VisualStateManager.VisualStateGroups> 
         <ContentControl 
          x:Name="ButtonContent" 
          Content="{TemplateBinding Content}" 
          ContentTemplate="{TemplateBinding ContentTemplate}" 
          VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
          Margin="{TemplateBinding Padding}"> 
         </ContentControl> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

Я также попытался поставить анимации в визуальные состояния «нормальные» и «нажатые» без каких-либо переходов. Но результат был тот же. Он просто привязывается к масштабу = 1, когда кнопка больше не нажата.

Я программирую для Windows Phone 8.0 silverlight.

Надеюсь, вы, ребята, можете мне помочь.

Спасибо, Кевин

+0

Ваша проблема: вы не используете свой VSM правильно, ваши Stoyboards должны быть в VisualState, ваш VisualTransition - это то, что должно содержать ваши EasingFunctions в ваших состояниях «From» и «To». Если я получу свободное время, я вернусь к этому и покажу вам, как это сделать правильно. Это не большое дело. –

ответ

1

Трюк заключается в том, чтобы определить только визуальные состояния, которые вас интересуют. В этом случае вас интересуют только «нажатые» и «нормальные», поэтому их определяют только. Вот пример:

<Button.Template> 
      <ControlTemplate TargetType="Button"> 
       <ContentPresenter x:Name="LayoutRoot" RenderTransformOrigin="0.5 0.5"> 
        <ContentPresenter.RenderTransform> 
         <ScaleTransform/> 
        </ContentPresenter.RenderTransform> 
        <ContentPresenter.Foreground> 
         <SolidColorBrush Color="White"/> 
        </ContentPresenter.Foreground> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="CommonStates"> 
          <VisualState x:Name="Normal"> 
           <Storyboard Duration="0:0:0.5"> 
            <DoubleAnimation Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(ContentPresenter.RenderTransform).(ScaleTransform.ScaleX)" 
             To="1" Duration="0:0:0.5"/> 
            <DoubleAnimation Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(ContentPresenter.RenderTransform).(ScaleTransform.ScaleY)" 
             To="1" Duration="0:0:0.5"/> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="Pressed"> 
           <Storyboard Duration="0:0:0.5"> 
            <DoubleAnimation Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(ContentPresenter.RenderTransform).(ScaleTransform.ScaleX)" 
             To="0.8" Duration="0:0:0.5"/> 
            <DoubleAnimation Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(ContentPresenter.RenderTransform).(ScaleTransform.ScaleY)" 
             To="0.8" Duration="0:0:0.5"/> 
            <ColorAnimation Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(ContentPresenter.Foreground).(SolidColorBrush.Color)" 
                To="Red" Duration="0"/> 
           </Storyboard> 
          </VisualState> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 
       </ContentPresenter> 
      </ControlTemplate> 
     </Button.Template> 

Как только визуальное состояние менеджер изменяет состояние, анимации будут сброшены, если новое государство не не объявлен в шаблоне. F.E. если вы определяете только «нажатое» состояние, кнопка останется в масштабе 0,8. Только если вы также объявите «Обычный», анимация будет сброшена.

0

Итак, глядя на ваши вещи ... у вас есть еще один вопрос в том, как вы настраиваете ваш RenderTransform явно. Оставьте эту вещь открытой, так как мы взаимодействуем с ней динамически (посмотрите на Grid.RenderTransform на моем примере). Вам также нужно установить RenderTransformOrigin на ваш buttonLayoutRoot, чтобы он знал, что вы тоже отскакиваете.

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

<Style x:Key="StandardButtonStyle" TargetType="Button"> 
    <Setter Property="Background" Value="Red" /> 
    <Setter Property="Foreground" Value="Blue" /> 
    <Setter Property="FontWeight" Value="SemiBold"/> 
    <Setter Property="HorizontalContentAlignment" Value="Center" /> 
    <Setter Property="VerticalContentAlignment" Value="Center" /> 
    <Setter Property="Cursor" Value="Hand"/> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="Button"> 
       <Grid x:Name="Container" 
         RenderTransformOrigin="0.5,0.5" Cursor="{TemplateBinding Cursor}"> 
        <Grid.RenderTransform> 
         <TransformGroup> 
          <ScaleTransform /> 
          <SkewTransform /> 
          <RotateTransform /> 
          <TranslateTransform /> 
         </TransformGroup> 
        </Grid.RenderTransform> 
        <VisualStateManager.VisualStateGroups> 
         <VisualStateGroup x:Name="CommonStates"> 
          <VisualStateGroup.Transitions> 
           <VisualTransition From="MouseOver" 
                GeneratedDuration="0:0:0.1" 
                To="Pressed"> 
            <VisualTransition.GeneratedEasingFunction> 
             <ExponentialEase EasingMode="EaseIn" Exponent="-2" /> 
            </VisualTransition.GeneratedEasingFunction> 
           </VisualTransition> 
           <VisualTransition From="Pressed" 
                GeneratedDuration="0:0:0.1" 
                To="MouseOver"> 
            <VisualTransition.GeneratedEasingFunction> 
             <ExponentialEase EasingMode="EaseOut" Exponent="0" /> 
            </VisualTransition.GeneratedEasingFunction> 
           </VisualTransition> 
          </VisualStateGroup.Transitions> 
          <VisualState x:Name="Normal" /> 
          <VisualState x:Name="MouseOver"> 
           <Storyboard> 
            <ObjectAnimationUsingKeyFrames Duration="00:00:00" 
                    Storyboard.TargetName="MouseOverState" Storyboard.TargetProperty="(UIElement.Visibility)"> 
             <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Visible"/> 
            </ObjectAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="Pressed"> 
           <Storyboard> 
            <ObjectAnimationUsingKeyFrames Duration="00:00:00" 
                    Storyboard.TargetName="PressedState" Storyboard.TargetProperty="(UIElement.Visibility)"> 
             <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Visible"/> 
            </ObjectAnimationUsingKeyFrames> 
            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Container" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"> 
             <EasingDoubleKeyFrame KeyTime="0:0:0.01" Value="1.05" /> 
            </DoubleAnimationUsingKeyFrames> 
            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="Container" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"> 
             <EasingDoubleKeyFrame KeyTime="0:0:0.01" Value="1.05" /> 
            </DoubleAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="Disabled"> 
           <Storyboard> 
            <ObjectAnimationUsingKeyFrames Duration="00:00:00" 
                    Storyboard.TargetName="DisabledState" Storyboard.TargetProperty="(UIElement.Visibility)"> 
             <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Visible"/> 
            </ObjectAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
         </VisualStateGroup> 
         <VisualStateGroup x:Name="FocusStates"> 
          <VisualState x:Name="Focused"> 
           <Storyboard> 
            <ObjectAnimationUsingKeyFrames Duration="00:00:00" 
                    Storyboard.TargetName="FocusedState" Storyboard.TargetProperty="(UIElement.Visibility)"> 
             <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Visible"/> 
            </ObjectAnimationUsingKeyFrames> 
           </Storyboard> 
          </VisualState> 
          <VisualState x:Name="Unfocused" /> 
         </VisualStateGroup> 
        </VisualStateManager.VisualStateGroups> 
        <Border x:Name="BaseBackground" 
          Background="{TemplateBinding Background}" 
          BorderBrush="{TemplateBinding BorderBrush}" 
          BorderThickness="{TemplateBinding BorderThickness}"/> 
        <Border x:Name="MouseOverState" 
          BorderThickness="{TemplateBinding BorderThickness}" 
          Visibility="Collapsed"/> 
        <Border x:Name="PressedState" 
          BorderThickness="{TemplateBinding BorderThickness}" 
          Visibility="Collapsed"/> 
        <Border x:Name="FocusedState" 
          Background="{TemplateBinding Background}" 
          Visibility="Collapsed"/> 
        <ContentControl x:Name="contentPresenter" 
            Margin="{TemplateBinding Padding}" 
            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
            VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
            Content="{TemplateBinding Content}" 
            ContentTemplate="{TemplateBinding ContentTemplate}" 
            FontFamily="{TemplateBinding FontFamily}" 
            FontSize="{TemplateBinding FontSize}" 
            FontWeight="{TemplateBinding FontWeight}" 
            Foreground="{TemplateBinding Foreground}" 
            IsTabStop="False"/> 
        <Border x:Name="DisabledState" 
          Background="White" 
          Visibility="Collapsed"/> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Надеюсь, это поможет, ура! :)

+0

Спасибо за ответ. Я попробую это завтра. Тем временем я просто установил переход по умолчанию с продолжительностью 300 мс, который работает. Но это не идеально. –

Смежные вопросы