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不会更新,直到达到最大值.
所以我的问题是,如何为滑块创建我想要的"动画"?请指出正确的方向.:) 谢谢!
您可以使用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)