2012-01-13 21 views
2

私はボタンとスライダを持っていますので、ボタンを押したときに最大値に達するまでスライダを1ステップ刻みします。しかし、私はそれを動作させることはありません。ボタンをクリックすると、しばらく眠った後、各ティックを表示せずにスライダを最大値で表示します。Slider "animation" in 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であるため、アニメーションはアニメーションフレームレートに基づいてダブル値を計算してターゲットに適用します。 (アニメーションフレームレートはデフォルトで60fpsですが、それを減らしたとしても、開始値によっては偶数の値が得られる場合もあります)。 DoubleAnimationに値だけを使用するように指示する方法はわかりません。 Int32Animationクラスが存在しますが、その型をDouble型のSlider.Valueに適用することはできません。

ここで私のハックな解決策(私はそれほど好きではない)です: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

+0

このストーリーボードで「TickFrequency = "1"」の設定を使用することはできますか?今はスムーズにアニメートしていますが、これはうまく見えますが、「1」、「2」、「0.1116」などのヒットを確認する必要があります。 – Ragowit

+0

上記の更新を参照してください... –