WPF中的滑块"动画"?

Rag*_*wit 3 wpf user-interface animation slider

我有一个按钮和一个滑块,当我按下按钮时,我希望滑块勾选一步,直到达到最大值.但是,我没有让它工作.单击按钮后,它会休眠一段时间,然后将滑块显示为最大值,而不显示每个刻度.

这是我的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>
Run Code Online (Sandbox Code Playgroud)

这是我的代码背后:

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
Run Code Online (Sandbox Code Playgroud)

我试图使用动态资源,但结果是一样的.

XAML:

<Window.Resources>
    <sys:Double x:Key="AnimationSliderValue">0</sys:Double>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)

然后我将XAML中滑块的值更改为:

Value="{DynamicResource AnimationSliderValue}"
Run Code Online (Sandbox Code Playgroud)

并将后面的代码更改为:

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

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

所以我的问题是,如何为滑块创建我想要的"动画"?请指出正确的方向.:) 谢谢!

Ere*_*mez 5

您可以使用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>
Run Code Online (Sandbox Code Playgroud)

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

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"));
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:您需要在项目引用中添加PresentationFramework.dll才能访问代码中的Storyboard类.

更新下面的评论

您希望仅使用动画将整个整数递增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>
Run Code Online (Sandbox Code Playgroud)

这是添加到MainWindow类的依赖属性:

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"));
    }
}
Run Code Online (Sandbox Code Playgroud)