2012-01-13 88 views
2

我有一个按钮和一个滑块,当我按下按钮时,我想让滑块勾选一个步骤,直到达到其最大值。但是,我没有得到它的工作。一旦我点击该按钮,它会休眠一段时间,然后以最大值显示滑块,而不显示每个刻度。WPF中的滑块“动画”?

这里是我的XAML代码:

<StackPanel Orientation="Horizontal"> 
    <Button x:Name="AnimationGoButton" Content="Go" /> 
    <Slider x:Name="AnimationSlider" TickFrequency="1" TickPlacement="BottomRight" IsSnapToTickEnabled="True" Width="200" Maximum="20" Value="0" /> 
</StackPanel> 

这里是我的代码背后:

Private Sub AnimationGoButton_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles AnimationGoButton.Click 
    While (Me.AnimationSlider.Value < Me.AnimationSlider.Maximum) 
     Me.AnimationSlider.Value += 1 
     System.Threading.Thread.Sleep(100) 
    End While 
End Sub 

我曾尝试使用一个动态资源,但结果是一样的。

XAML:

<Window.Resources> 
    <sys:Double x:Key="AnimationSliderValue">0</sys:Double> 
</Window.Resources> 

然后,我改变了价值滑块XAML到:

Value="{DynamicResource AnimationSliderValue}" 

,并切换到后面的代码:

While (Me.AnimationSlider.Value < Me.AnimationSlider.Maximum) 
    Resources("AnimationSliderValue") += 1 
    System.Threading.Thread.Sleep(100) 
End While 

但正如我说,结果是一样的。当我按下按钮时,UI不会更新,直到达到最大值。

所以我的问题是,我该如何创建这个“动画”我想要的滑块?请指点我正确的方向看。 :) 谢谢!

回答

4

您可以使用Storyboard来制作动画。

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525" x:Name="userControl"> 
<Window.Resources> 
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 
    <Storyboard x:Key="SlideUpAnimation"> 
     <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(RangeBase.Value)" Storyboard.TargetName="slider1"> 
      <EasingDoubleKeyFrame KeyTime="0:0:1" Value="10"/> 
     </DoubleAnimationUsingKeyFrames> 
    </Storyboard> 
    <Storyboard x:Key="SlideDownAnimation"> 
     <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(RangeBase.Value)" Storyboard.TargetName="slider1"> 
      <SplineDoubleKeyFrame KeyTime="0:0:1" Value="0"/> 
     </DoubleAnimationUsingKeyFrames> 
    </Storyboard> 
</Window.Resources> 
<Window.Triggers> 
    <EventTrigger RoutedEvent="FrameworkElement.Loaded"> 
     <BeginStoryboard Storyboard="{StaticResource SlideUpAnimation}"/> 
    </EventTrigger> 
</Window.Triggers> 
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top"> 
    <Button x:Name="btnSlideDown" Click="btnSlideDown_Click" Content="Slide Down" HorizontalAlignment="Center" VerticalAlignment="Center"/> 
    <Slider Height="23" x:Name="slider1" Width="100" /> 
    <Button x:Name="btnSlideUp" Click="btnSlideUp_Click" HorizontalAlignment="Center" VerticalAlignment="Center" Content="Slide Up" /> 
</StackPanel> 

然后启动按钮点击故事板:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void btnSlideUp_Click(object sender, System.Windows.RoutedEventArgs e) 
    { 
     this.BeginStoryboard((Storyboard)this.FindResource("SlideUpAnimation")); 
    } 

    private void btnSlideDown_Click(object sender, System.Windows.RoutedEventArgs e) 
    { 
     this.BeginStoryboard((Storyboard)this.FindResource("SlideDownAnimation")); 
    } 
} 

注意:您需要添加PresentationFramework.dll项目中的引用,以访问代码的故事板类。根据注释

更新下面

你想只用动画全部整数递增Slider.Value。由于目标值类型为Double,动画会根据动画帧速率计算并将双倍值应用于目标。 (默认情况下动画帧速率为60 fps,但即使您确实减少了动画帧速率,依据初始值,仍然可能会甚至可能不会给您数值)。我不知道任何告诉DoubleAnimation只使用偶数值的方法。存在一个Int32Animation类,但不能将其应用于类型为double的Slider.Value。

这是我的hacky解决方案(我不太喜欢):向父级添加SliderIntValue(Int32)依赖项属性(例如MainWindow或者您的viewmodel)并使用双向绑定将其绑定到Slider.Value 。 Binding类会神奇地处理类型转换。然后应用动画到SliderIntValue而不是滑块本身:

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525" x:Name="userControl"> 
<Window.Resources> 
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 
    <Storyboard x:Key="SlideUpAnimation"> 
     <Int32AnimationUsingKeyFrames Storyboard.TargetProperty="SliderIntValue" Storyboard.TargetName="userControl"> 
      <EasingInt32KeyFrame KeyTime="0:0:1" Value="10"/> 
     </Int32AnimationUsingKeyFrames> 
    </Storyboard> 
    <Storyboard x:Key="SlideDownAnimation"> 
     <Int32AnimationUsingKeyFrames Storyboard.TargetProperty="SliderIntValue" Storyboard.TargetName="userControl"> 
      <EasingInt32KeyFrame KeyTime="0:0:1" Value="0"/> 
     </Int32AnimationUsingKeyFrames> 
    </Storyboard> 
</Window.Resources> 
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top"> 
    <Button x:Name="btnSlideDown" Click="btnSlideDown_Click" Content="Slide Down" HorizontalAlignment="Center" VerticalAlignment="Center"/> 
    <Slider Height="23" x:Name="slider1" Width="100" IsSnapToTickEnabled="True" Value="{Binding SliderIntValue, ElementName=userControl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
    <Button x:Name="btnSlideUp" Click="btnSlideUp_Click" HorizontalAlignment="Center" VerticalAlignment="Center" Content="Slide Up" /> 
    <TextBox TextWrapping="Wrap" Text="{Binding Value, ElementName=slider1}" Margin="20,0,0,0"/> 
</StackPanel> 

而这里的依赖属性添加到主窗口类:

public partial class MainWindow : Window 
{ 
    public static readonly DependencyProperty SliderIntValueProperty = DependencyProperty.Register("SliderIntValue", 
       typeof(int), typeof(MainWindow)); 

    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void btnSlideUp_Click(object sender, System.Windows.RoutedEventArgs e) 
    { 
     this.BeginStoryboard((Storyboard)this.FindResource("SlideUpAnimation")); 
    } 

    private void btnSlideDown_Click(object sender, System.Windows.RoutedEventArgs e) 
    { 
     this.BeginStoryboard((Storyboard)this.FindResource("SlideDownAnimation")); 
    } 
} 
+0

谢谢你,这对我帮助很大。 – Ragowit 2012-01-16 10:35:28

+0

是否有可能让此故事板使用“TickFrequency =”1“” - 设置?现在它动画也很流畅,看起来不错,但是我需要检查它是什么时候点击“1”,“2”而不是“0.1116”等等。 – Ragowit 2012-01-16 10:45:10

+0

查看上面的更新... – 2012-01-17 10:26:52