【问题标题】:Animate Expander in WPFWPF 中的动画扩展器
【发布时间】:2010-11-21 15:35:57
【问题描述】:

如何为 Wpf 扩展器控件的展开和折叠操作设置动画?

【问题讨论】:

    标签: animation wpf-controls expander


    【解决方案1】:

    我在 Code Project 上找到了这篇文章:Read Here

    作者创建了自己的 SimpleExpander 模板,然后为其添加了伸展动画。他甚至在上面添加了一个漂亮的旋转箭头。

    【讨论】:

      【解决方案2】:

      我根据msdn Stylethis answer 中的点创建了一个样式:

       <Window x:Class="Test.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
          xmlns:local="clr-namespace:Test" 
          xmlns:sys="clr-namespace:System;assembly=mscorlib"
          xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
          mc:Ignorable="d">
      
      <Window.Resources>
          <Color x:Key="WindowColor">#FFE8EDF9</Color>
          <Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
          <Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
      
          <Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
          <Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
          <Color x:Key="DisabledForegroundColor">#FF888888</Color>
      
          <Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
          <Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
      
          <Color x:Key="ControlLightColor">White</Color>
          <Color x:Key="ControlMediumColor">#FF7381F9</Color>
          <Color x:Key="ControlDarkColor">#FF211AA9</Color>
      
          <Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
          <Color x:Key="ControlPressedColor">#FF211AA9</Color>
      
      
          <Color x:Key="GlyphColor">#FF444444</Color>
          <Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
      
          <!--Border colors-->
          <Color x:Key="BorderLightColor">#FFCCCCCC</Color>
          <Color x:Key="BorderMediumColor">#FF888888</Color>
          <Color x:Key="BorderDarkColor">#FF444444</Color>
      
          <Color x:Key="PressedBorderLightColor">#FF888888</Color>
          <Color x:Key="PressedBorderDarkColor">#FF444444</Color>
      
          <Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
          <Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
      
          <Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
      
          <!--Control-specific resources.-->
          <Color x:Key="HeaderTopColor">#FFC5CBF9</Color>
          <Color x:Key="DatagridCurrentCellBorderColor">Black</Color>
          <Color x:Key="SliderTrackDarkColor">#FFC5CBF9</Color>
      
          <Color x:Key="NavButtonFrameColor">#FF3843C4</Color>
      
          <LinearGradientBrush x:Key="MenuPopupBrush"
                         EndPoint="0.5,1"
                         StartPoint="0.5,0">
              <GradientStop Color="{DynamicResource ControlLightColor}"
                    Offset="0" />
              <GradientStop Color="{DynamicResource ControlMediumColor}"
                    Offset="0.5" />
              <GradientStop Color="{DynamicResource ControlLightColor}"
                    Offset="1" />
          </LinearGradientBrush>
      
          <LinearGradientBrush x:Key="ProgressBarIndicatorAnimatedFill"
                         StartPoint="0,0"
                         EndPoint="1,0">
              <LinearGradientBrush.GradientStops>
                  <GradientStopCollection>
                      <GradientStop Color="#000000FF"
                        Offset="0" />
                      <GradientStop Color="#600000FF"
                        Offset="0.4" />
                      <GradientStop Color="#600000FF"
                        Offset="0.6" />
                      <GradientStop Color="#000000FF"
                        Offset="1" />
                  </GradientStopCollection>
              </LinearGradientBrush.GradientStops>
          </LinearGradientBrush>
      
          <ControlTemplate x:Key="ExpanderToggleButton"
                     TargetType="{x:Type ToggleButton}">
              <Border x:Name="Border"
              CornerRadius="2,0,0,0"
              BorderThickness="0,0,1,0">
                  <Border.Background>
                      <LinearGradientBrush EndPoint="0.5,1"
                               StartPoint="0.5,0">
                          <GradientStop Color="{DynamicResource ControlLightColor}" />
                          <GradientStop Color="{DynamicResource ControlMediumColor}"
                          Offset="1" />
                      </LinearGradientBrush>
                  </Border.Background>
                  <Border.BorderBrush>
                      <LinearGradientBrush StartPoint="0,0"
                               EndPoint="0,1">
                          <LinearGradientBrush.GradientStops>
                              <GradientStopCollection>
                                  <GradientStop Color="{DynamicResource BorderLightColor}"
                              Offset="0.0" />
                                  <GradientStop Color="{DynamicResource BorderDarkColor}"
                              Offset="1.0" />
                              </GradientStopCollection>
                          </LinearGradientBrush.GradientStops>
                      </LinearGradientBrush>
      
                  </Border.BorderBrush>
                  <VisualStateManager.VisualStateGroups>
                      <VisualStateGroup x:Name="CommonStates">
                          <VisualState x:Name="Normal" />
                          <VisualState x:Name="MouseOver">
                              <Storyboard>
                                  <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                              Storyboard.TargetProperty="(Panel.Background).
                    (GradientBrush.GradientStops)[1].(GradientStop.Color)">
                                      <EasingColorKeyFrame KeyTime="0"
                                       Value="{StaticResource ControlMouseOverColor}" />
                                  </ColorAnimationUsingKeyFrames>
                              </Storyboard>
                          </VisualState>
                          <VisualState x:Name="Pressed">
                              <Storyboard>
                                  <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                              Storyboard.TargetProperty="(Panel.Background).
                    (GradientBrush.GradientStops)[1].(GradientStop.Color)">
                                      <EasingColorKeyFrame KeyTime="0"
                                       Value="{StaticResource ControlPressedColor}" />
                                  </ColorAnimationUsingKeyFrames>
                              </Storyboard>
                          </VisualState>
                          <VisualState x:Name="Disabled">
                              <Storyboard>
                                  <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                              Storyboard.TargetProperty="(Panel.Background).
                    (GradientBrush.GradientStops)[1].(GradientStop.Color)">
                                      <EasingColorKeyFrame KeyTime="0"
                                       Value="{StaticResource DisabledControlDarkColor}" />
                                  </ColorAnimationUsingKeyFrames>
                                  <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                              Storyboard.TargetProperty="(Border.BorderBrush).
                    (GradientBrush.GradientStops)[1].(GradientStop.Color)">
                                      <EasingColorKeyFrame KeyTime="0"
                                       Value="{StaticResource DisabledBorderLightColor}" />
                                  </ColorAnimationUsingKeyFrames>
                              </Storyboard>
                          </VisualState>
                      </VisualStateGroup>
                      <VisualStateGroup x:Name="CheckStates">
                          <VisualState x:Name="Checked">
                              <Storyboard>
                                  <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                               Storyboard.TargetName="CollapsedArrow">
                                      <DiscreteObjectKeyFrame KeyTime="0"
                                          Value="{x:Static Visibility.Hidden}" />
                                  </ObjectAnimationUsingKeyFrames>
                                  <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                               Storyboard.TargetName="ExpandededArrow">
                                      <DiscreteObjectKeyFrame KeyTime="0"
                                          Value="{x:Static Visibility.Visible}" />
                                  </ObjectAnimationUsingKeyFrames>
                              </Storyboard>
                          </VisualState>
                          <VisualState x:Name="Unchecked" />
                          <VisualState x:Name="Indeterminate" />
                      </VisualStateGroup>
                  </VisualStateManager.VisualStateGroups>
                  <Grid>
                      <Path x:Name="CollapsedArrow"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Data="M 0 0 L 4 4 L 8 0 Z">
                          <Path.Fill>
                              <SolidColorBrush Color="{DynamicResource GlyphColor}" />
                          </Path.Fill>
                      </Path>
                      <Path x:Name="ExpandededArrow"
                HorizontalAlignment="Center"
                VerticalAlignment="Center"
                Visibility="Collapsed"
                Data="M 0 4 L 4 0 L 8 4 Z">
                          <Path.Fill>
                              <SolidColorBrush Color="{DynamicResource GlyphColor}" />
                          </Path.Fill>
                      </Path>
                  </Grid>
              </Border>
          </ControlTemplate>
      
          <Style TargetType="{x:Type Expander}">
              <Setter Property="Template">
                  <Setter.Value>
                      <ControlTemplate TargetType="{x:Type Expander}">
                          <Grid>
                              <Grid.RowDefinitions>
                                  <RowDefinition Height="Auto" />
                                  <RowDefinition x:Name="ContentRow" >
                                      <RowDefinition.Resources>
                                          <local:MultiplyConverter x:Key="multiplyConverter"/>
                                      </RowDefinition.Resources>
                                      <RowDefinition.Tag>
                                          <sys:Double>0.0</sys:Double>
                                      </RowDefinition.Tag>
                                      <RowDefinition.Height>
                                          <MultiBinding Converter="{StaticResource multiplyConverter}">
                                              <Binding Path="DesiredSize.Height" ElementName="Content" />
                                              <Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
                                          </MultiBinding>
                                      </RowDefinition.Height>
                                  </RowDefinition>
                              </Grid.RowDefinitions>
                              <VisualStateManager.VisualStateGroups>
                                  <VisualStateGroup x:Name="CommonStates">
                                      <VisualState x:Name="Normal" />
                                      <VisualState x:Name="MouseOver" />
                                      <VisualState x:Name="Disabled">
                                          <Storyboard>
                                              <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                    Storyboard.TargetProperty="(Panel.Background).
                          (GradientBrush.GradientStops)[1].(GradientStop.Color)">
                                                  <EasingColorKeyFrame KeyTime="0"
                                             Value="{StaticResource DisabledControlDarkColor}" />
                                              </ColorAnimationUsingKeyFrames>
                                              <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                    Storyboard.TargetProperty="(Border.BorderBrush).
                          (GradientBrush.GradientStops)[1].(GradientStop.Color)">
                                                  <EasingColorKeyFrame KeyTime="0"
                                             Value="{StaticResource DisabledBorderLightColor}" />
                                              </ColorAnimationUsingKeyFrames>
                                          </Storyboard>
                                      </VisualState>
                                  </VisualStateGroup>
                              </VisualStateManager.VisualStateGroups>
                              <Border x:Name="Border" Grid.Row="0" BorderThickness="1" CornerRadius="2,2,0,0">
                                  <Border.BorderBrush>
                                      <LinearGradientBrush EndPoint="0,1"
                                       StartPoint="0,0">
                                          <GradientStop Color="{DynamicResource BorderLightColor}"
                                  Offset="0" />
                                          <GradientStop Color="{DynamicResource BorderDarkColor}"
                                  Offset="1" />
                                      </LinearGradientBrush>
                                  </Border.BorderBrush>
                                  <Border.Background>
      
                                      <LinearGradientBrush StartPoint="0,0"
                                       EndPoint="0,1">
                                          <LinearGradientBrush.GradientStops>
                                              <GradientStopCollection>
                                                  <GradientStop Color="{DynamicResource ControlLightColor}"
                                      Offset="0.0" />
                                                  <GradientStop Color="{DynamicResource ControlMediumColor}"
                                      Offset="1.0" />
                                              </GradientStopCollection>
                                          </LinearGradientBrush.GradientStops>
                                      </LinearGradientBrush>
      
                                  </Border.Background>
                                  <Grid>
                                      <Grid.ColumnDefinitions>
                                          <ColumnDefinition Width="20" />
                                          <ColumnDefinition Width="*" />
                                      </Grid.ColumnDefinitions>
                                      <ToggleButton OverridesDefaultStyle="True"
                                Template="{StaticResource ExpanderToggleButton}"
                                IsChecked="{Binding IsExpanded, Mode=TwoWay, 
                      RelativeSource={RelativeSource TemplatedParent}}">
                                          <ToggleButton.Background>
                                              <LinearGradientBrush EndPoint="0.5,1"
                                           StartPoint="0.5,0">
                                                  <GradientStop Color="{DynamicResource ControlLightColor}"
                                      Offset="0" />
                                                  <GradientStop Color="{DynamicResource ControlMediumColor}"
                                      Offset="1" />
                                              </LinearGradientBrush>
                                          </ToggleButton.Background>
                                      </ToggleButton>
                                      <ContentPresenter Grid.Column="1" Margin="4" ContentSource="Header" RecognizesAccessKey="True" />
                                  </Grid>
                              </Border>
                              <Border x:Name="Content" Grid.Row="1"  BorderThickness="1,0,1,1" CornerRadius="0,0,2,2">
                                  <Border.BorderBrush>
                                      <SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
                                  </Border.BorderBrush>
                                  <Border.Background>
                                      <SolidColorBrush Color="{DynamicResource ContentAreaColorDark}" />
                                  </Border.Background>
                                  <ContentPresenter Margin="4" />
                              </Border>
      
                          </Grid>
                          <ControlTemplate.Triggers> 
                              <Trigger Property="IsExpanded" Value="True">
                                  <Trigger.EnterActions>
                                      <BeginStoryboard>
                                          <Storyboard>
                                              <DoubleAnimation Storyboard.TargetName="ContentRow" Storyboard.TargetProperty="Tag" From="0" To="1" Duration="0:0:1"/>
                                          </Storyboard>
                                      </BeginStoryboard>
                                  </Trigger.EnterActions>
                                  <Trigger.ExitActions>
                                      <BeginStoryboard>
                                          <Storyboard>
                                              <DoubleAnimation Storyboard.TargetName="ContentRow" Storyboard.TargetProperty="Tag" From="1" To="0" Duration="0:0:1"/>
                                          </Storyboard>
                                      </BeginStoryboard>
                                  </Trigger.ExitActions>
                              </Trigger>
      
                          </ControlTemplate.Triggers>
                      </ControlTemplate>
                  </Setter.Value>
              </Setter>
          </Style>
      </Window.Resources>
      <StackPanel>  
          <Expander  Header="Canny" >
              <StackPanel>
                  <Button Content="A" />
                  <Button Content="B" />
                  <Button Content="C" />
              </StackPanel>
          </Expander>
      
          <Expander Header="Sobel" >
              <StackPanel>
                  <Button Content="A" />
                  <Button Content="B" />
                  <Button Content="C" />
              </StackPanel>
          </Expander>
          <Expander Header="LoG" >
              <StackPanel>
                  <Button Content="A" />
                  <Button Content="B" />
                  <Button Content="C" />
              </StackPanel>
          </Expander>
      
      </StackPanel>
      
      
      </Window>
      

      需要这个转换器:

      public class MultiplyConverter : IMultiValueConverter
      {
          public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
          {
              return new GridLength((double)values[0] * (double)values[1], GridUnitType.Pixel);
          }
      
          public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
          {
              throw new NotImplementedException();
          }
      }
      

      主要是在模板中将DoubleAnimation设置在ContentRow.Height上。但是,您需要使用MultiBinding 来绑定此动画的To 属性。

      【讨论】:

      • 这是一个很好的方法。我遇到的问题是扩展器包含动态的事物列表,并且当从集合中删除项目时让它调整大小是很棘手的。有什么想法吗?
      猜你喜欢
      • 2016-07-31
      • 2021-11-14
      • 1970-01-01
      • 2010-11-19
      • 1970-01-01
      • 2011-01-18
      • 1970-01-01
      • 2012-02-27
      • 1970-01-01
      相关资源
      最近更新 更多