WPF Datagrid ListBox ScrollViewer 上下滚动(动画)
采用属性动画的方式。由于动画绑定时需要绑定依赖属性,但ScrollViewer没有水平偏移和垂直偏移的依赖属性,所以需要通过附加属性的方式添加水平和垂直的依赖属性
public static class ScrollViewerBehavior { public static readonly DependencyProperty HorizontalOffsetProperty = DependencyProperty.RegisterAttached("HorizontalOffset", typeof(double), typeof(ScrollViewerBehavior), new UIPropertyMetadata(0.0, OnHorizontalOffsetChanged)); public static void SetHorizontalOffset(FrameworkElement target, double value) => target.SetValue(HorizontalOffsetProperty, value); public static double GetHorizontalOffset(FrameworkElement target) => (double)target.GetValue(HorizontalOffsetProperty); private static void OnHorizontalOffsetChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) => (target as ScrollViewer)?.ScrollToHorizontalOffset((double)e.NewValue); public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.RegisterAttached("VerticalOffset", typeof(double), typeof(ScrollViewerBehavior), new UIPropertyMetadata(0.0, OnVerticalOffsetChanged)); public static void SetVerticalOffset(FrameworkElement target, double value) => target.SetValue(VerticalOffsetProperty, value); public static double GetVerticalOffset(FrameworkElement target) => (double)target.GetValue(VerticalOffsetProperty); private static void OnVerticalOffsetChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) => (target as ScrollViewer)?.ScrollToVerticalOffset((double)e.NewValue); }
xml 代码
<ScrollViewer HorizontalScrollBarVisibility="Disabled" Grid.Column="1" VerticalScrollBarVisibility="Hidden" HorizontalAlignment="Stretch" x:Name="ScrollViewertest" Margin="10,0,0,0" > <!--填充控件--> </ScrollViewer>
动画绑定,并开始动画
private Void ScrollViewerAnimation(int TotalCount)// TotalCount 共有多少条数据
{
int LineCount=5;//每行显示5条数据
Storyboard storyboard = new Storyboard();
TimeSpan ts = new TimeSpan(0, 0, 25);//向下滚动耗时
double end = 200;; //向下滚动距离,可滚动数据源个数调整
DoubleAnimation TopToButtomAnimation = new DoubleAnimation();
TopToButtomAnimation.EasingFunction = new SineEase { EasingMode = EasingMode.EaseInOut };//EasingMode:滚动方式
TopToButtomAnimation.From = 0;
TopToButtomAnimation.To = end;
TopToButtomAnimation.Duration = new Duration(ts);
TopToButtomAnimation.AutoReverse = true; //ture:来回滚动,False:只向下滚动
TopToButtomAnimation.SpeedRatio = 1;//滚动速率
storyboard.Duration = new Duration(TimeSpan.FromSeconds(50));//上下滚动总时长
storyboard.Children.Add(TopToButtomAnimation);
//动画绑定
Storyboard.SetTarget(TopToButtomAnimation, ScrollViewertest);
Storyboard.SetTargetName(TopToButtomAnimation, ScrollViewertest.Name);
Storyboard.SetTargetProperty(TopToButtomAnimation, new PropertyPath(ScrollViewerBehavior.VerticalOffsetProperty));
storyboard.RepeatBehavior = RepeatBehavior.Forever; //循环滚动
storyboard.FillBehavior = FillBehavior.HoldEnd;
storyboard.Begin();
}
List和DataGrid滚动都可以采取该方式,控制控件的ScrollViewer 进行滚动。
private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) { DependencyObject child = VisualTreeHelper.GetChild(obj, i); if (child != null && child is childItem) return (childItem)child; else { childItem childOfChild = FindVisualChild<childItem>(child); if (childOfChild != null) return childOfChild; } } return null; }
<Listbox X:Name="_Listbox"/>
private void ListAnimation(int TotalCount) { scrollViewer = FindVisualChild<ScrollViewer>(this._Listbox); Storyboard storyboard = new Storyboard(); TimeSpan ts = new TimeSpan(0, 2, 0); double end = 200;//滚动距离,可根据数据源个数调整 DoubleAnimation TopToButtomAnimation = new DoubleAnimation(); TopToButtomAnimation.EasingFunction = new SineEase { EasingMode = EasingMode.EaseOut }; TopToButtomAnimation.From = 0; TopToButtomAnimation.To = end; TopToButtomAnimation.Duration = new Duration(ts); TopToButtomAnimation.AutoReverse = true; TopToButtomAnimation.SpeedRatio = 1; storyboard.Duration = new Duration(TimeSpan.FromMinutes(4)); storyboard.Children.Add(TopToButtomAnimation); Storyboard.SetTarget(TopToButtomAnimation, scrollViewer); Storyboard.SetTargetName(TopToButtomAnimation, scrollViewer.Name); Storyboard.SetTargetProperty(TopToButtomAnimation, new PropertyPath(ScrollViewerBehavior.VerticalOffsetProperty)); storyboard.RepeatBehavior = RepeatBehavior.Forever; storyboard.Begin(); }