我有一个ListView控件来显示项目,我想提供一个滑动/滑动手势来选择一个项目.我使用
GestureRecognizer类来识别十字滑动手势,但我也希望通过水平移动所选项目来设置此手势的动画.
例如,这应该是来自iOS应用程序的此图像:
您可以创建一个行为来侦听项目上的ManipulationXYZ事件,并为这些项目上的RenderTransform设置动画.我给你写了一个简单的例子:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Input; using Windows.UI.Xaml; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media.Animation; using Microsoft.Xaml.Interactivity; namespace SOTestApp { [TypeConstraint(typeof(FrameworkElement))] public class SlideMechanicBehavior : DependencyObject,IBehavior { public void Attach(DependencyObject associatedObject) { AssociatedObject = associatedObject; var fw = (FrameworkElement) AssociatedObject; fw.ManipulationMode = ManipulationModes.TranslateX | ManipulationModes.System; fw.ManipulationDelta += fw_ManipulationDelta; fw.ManipulationCompleted += fw_ManipulationCompleted; if (fw.RenderTransform == null || fw.RenderTransform as TranslateTransform == null) { fw.RenderTransform = new TranslateTransform(); } } private const double Threshold = 100.0; private bool _canMove = true; public ICommand LeftDragCommand { get { return (ICommand)GetValue(LeftDragCommandProperty); } set { SetValue(LeftDragCommandProperty,value); } } public static readonly DependencyProperty LeftDragCommandProperty = DependencyProperty.Register("LeftDragCommand",typeof(ICommand),typeof(SlideMechanicBehavior),new PropertyMetadata(default(ICommand))); public ICommand RightDragCommand { get { return (ICommand)GetValue(RightDragCommandProperty); } set { SetValue(RightDragCommandProperty,value); } } public static readonly DependencyProperty RightDragCommandProperty = DependencyProperty.Register("RightDragCommand",new PropertyMetadata(default(ICommand))); void fw_ManipulationCompleted(object sender,ManipulationCompletedRoutedEventArgs e) { var fw = (FrameworkElement)AssociatedObject; var tr = (TranslateTransform) fw.RenderTransform; if (tr == null) return; tr.X = e.Cumulative.Translation.X; //call commands if (tr.X > Threshold && RightDragCommand != null && RightDragCommand.CanExecute(null)) RightDragCommand.Execute(null); //add params if necessary if (tr.X < -1 * Threshold && LeftDragCommand != null && LeftDragCommand.CanExecute(null)) LeftDragCommand.Execute(null); //add params if necessary //animate back var s = new Storyboard(); var d = new DoubleAnimation { To = 0.0,EasingFunction = new QuadraticEase(),Duration = TimeSpan.FromMilliseconds(300.0) }; Storyboard.SetTarget(d,tr); Storyboard.SetTargetProperty(d,"X"); //use nameof() in C# 6.0 s.Children.Add(d); _canMove = false; s.Completed += (o,o1) => _canMove = true; s.Begin(); } void fw_ManipulationDelta(object sender,ManipulationDeltaRoutedEventArgs e) { if(!_canMove) return; //move item var m = e.Delta.Translation.X; var fw = (FrameworkElement)AssociatedObject; var tr = (TranslateTransform) fw.RenderTransform; if (tr != null) tr.X += m; } public void Detach() { var fw = (FrameworkElement)AssociatedObject; fw.ManipulationCompleted -= fw_ManipulationCompleted; fw.ManipulationDelta -= fw_ManipulationDelta; AssociatedObject = null; } public DependencyObject AssociatedObject { get; private set; } } }
您可以在Xaml中使用它,如下所示:
<ItemsControl ItemsSource="{Binding TextList}" HorizontalAlignment="Center"> <ItemsControl.ItemTemplate> <DataTemplate> <Grid Background="Red"> <interactivity:Interaction.Behaviors> <local:SlideMechanicBehavior /> </interactivity:Interaction.Behaviors> <TextBlock FontSize="22" Text="{Binding }" /> </Grid> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>