2015-12-16 3 views
2

Я хочу создать анимированный стиль «Switch» для ToggleButton (например, на смартфонах).Состояние запуска для анимации ToggleButton

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

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

Следующий простой код показывает мою проблему: вместо переключателей я делаю кнопку 150 пикселей шириной, когда она проверяется.

<Window 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     x:Class="AnimationTest2.MainWindow" 
     Title="MainWindow" Height="350" Width="525"> 

    <Window.Resources> 
     <Style TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource {x:Type ToggleButton}}" x:Key="SwitchStyle"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource Self}}" Value="true"> 
        <DataTrigger.EnterActions> 
         <BeginStoryboard> 
          <Storyboard Storyboard.TargetProperty="Width"> 
           <DoubleAnimation To="150"/> 
          </Storyboard> 
         </BeginStoryboard> 
        </DataTrigger.EnterActions> 
        <DataTrigger.ExitActions> 
         <BeginStoryboard> 
          <Storyboard Storyboard.TargetProperty="Width"> 
           <DoubleAnimation To="50"/> 
          </Storyboard> 
         </BeginStoryboard> 
        </DataTrigger.ExitActions> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </Window.Resources> 

    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> 
     <ToggleButton Width="50" Content="Button" Style="{StaticResource ResourceKey=SwitchStyle}"/> 
     <ToggleButton Width="50" Content="Button" Style="{StaticResource ResourceKey=SwitchStyle}" IsChecked="True"/> 
    </StackPanel> 
</Window> 

Первый ToggleButton хорошо работает. Он не проверяется и оживляется до 150 пикселей при нажатии. Второй ToggleButton проверен по умолчанию и должен быть 150 пикселей сразу, но вместо этого он начинает расти, когда я запускаю свое приложение!

Как-то мне нужно определить начальное состояние для моих ToggleButtons в зависимости от состояния IsChecked и начать анимацию только по щелчку. Как я могу это достичь?

Я также попытался с VisualStateManager, так же, как в this answer, но тогда у меня такая же проблема ...

UPDATE

Это фактический рабочий переключатель, если кто-то не только заинтересованы в концепции корректуры из-:

<Style TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource {x:Type ToggleButton}}" x:Key="SwitchToggleButton"> 
     <Setter Property="BorderBrush" Value="Black"/> 
     <Setter Property="Background" Value="Gray"/> 
     <Setter Property="Foreground" Value="Black"/> 
     <Setter Property="Width" Value="70"/> 
     <Setter Property="Height" Value="30"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type ToggleButton}"> 
        <Grid> 
         <Border x:Name="BackBorder" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}"/> 
         <TextBlock x:Name="Off" Margin="30,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Center"><Run Text="OFF"/></TextBlock> 
         <TextBlock x:Name="On" Margin="0,0,30,0" VerticalAlignment="Center" HorizontalAlignment="Center"><Run Text="ON"/></TextBlock> 
         <Border x:Name="Slider" Background="LightGray" Width="30" Height="30" HorizontalAlignment="Left" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}"/> 
        </Grid> 
        <ControlTemplate.Triggers> 
         <EventTrigger RoutedEvent="Border.Loaded" SourceName="Slider"> 
          <SkipStoryboardToFill BeginStoryboardName="checkedSB" /> 
          <SkipStoryboardToFill BeginStoryboardName="checkedSB2" /> 
          <SkipStoryboardToFill BeginStoryboardName="uncheckedSB" /> 
          <SkipStoryboardToFill BeginStoryboardName="uncheckedSB2" /> 
         </EventTrigger> 
         <DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource Self}}" Value="true"> 
          <DataTrigger.EnterActions> 
           <BeginStoryboard x:Name="checkedSB"> 
            <Storyboard Storyboard.TargetProperty="Margin" Storyboard.TargetName="Slider"> 
             <ThicknessAnimation To="40,0,0,0" Duration="00:00:00.2"/> 
            </Storyboard> 
           </BeginStoryboard> 
           <BeginStoryboard x:Name="checkedSB2"> 
            <Storyboard Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)"> 
             <ColorAnimation To="LightSeaGreen" Duration="00:00:00.3"/> 
            </Storyboard> 
           </BeginStoryboard> 
          </DataTrigger.EnterActions> 
          <DataTrigger.ExitActions> 
           <BeginStoryboard x:Name="uncheckedSB"> 
            <Storyboard Storyboard.TargetProperty="Margin" Storyboard.TargetName="Slider"> 
             <ThicknessAnimation To="0" Duration="00:00:00.2"/> 
            </Storyboard> 
           </BeginStoryboard> 
           <BeginStoryboard x:Name="uncheckedSB2"> 
            <Storyboard Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)"> 
             <ColorAnimation To="{x:Null}" Duration="00:00:00.3"/> 
            </Storyboard> 
           </BeginStoryboard> 
          </DataTrigger.ExitActions> 
         </DataTrigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

ответ

3

Вы можете добавить объекты в SkipStoryboardToFillLoadedEventTrigger. Таким образом, код будет выглядеть так.

<Style.Triggers> 
    <EventTrigger RoutedEvent="ToggleButton.Loaded"> 
     <SkipStoryboardToFill BeginStoryboardName="checkedSB" /> 
     <SkipStoryboardToFill BeginStoryboardName="uncheckedSB" /> 
    </EventTrigger> 
    <DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource Self}}" Value="true"> 
     <DataTrigger.EnterActions> 
      <BeginStoryboard Name="checkedSB"> 
       <Storyboard Storyboard.TargetProperty="Width"> 
        <DoubleAnimation To="150"/> 
       </Storyboard> 
      </BeginStoryboard> 
     </DataTrigger.EnterActions> 
     <DataTrigger.ExitActions> 
      <BeginStoryboard Name="uncheckedSB"> 
       <Storyboard Storyboard.TargetProperty="Width"> 
        <DoubleAnimation To="50"/> 
       </Storyboard> 
      </BeginStoryboard> 
     </DataTrigger.ExitActions> 
    </DataTrigger> 
</Style.Triggers> 
+0

Работает как очарование - и так просто! Интересно, почему это не является частью примеров стиля ToggleButton из MS, потому что все стили, которые я видел с помощью анимаций, имели эту проблему. – JCH2k

+0

На самом деле я нашел его в справке Visual Studio 2010 на странице «Обзор раскадровки» =) Но я потратил больше времени, чем ожидалось, чтобы найти его. – bars222

+0

В моем реальном приложении мне пришлось сделать привязку EventTrigger к чему-то еще, например. '' и назовите одну из границ 'Border', чтобы он работал правильно с ленивой загрузкой. В противном случае у меня был начальный эффект снова ... Я напишу свой рабочий код выше ... – JCH2k

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