2012-01-13 90 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