标签:windows phone 8.1 实现元素拖曳效果 pointerpressed visualtreehelper pointermoved
前面有一篇博客涉及到手势和指针的用法,其中就有利用手势进行元素的拖拉操作,主要是ManipulationDelta:
博客地址: Windows Phone 8.1触控输入-----手势及指针
其实利用手势ManipulationDelta操作来实现元素拖拉的方法很简单,很实用。但是一旦要实现页面中多个控件元素
的拖拉,难免代码臃肿。其实我们可以抽象出这其中一致的功能代码,这样要实现某一个元素的拖拉效果只需调用共
通类中的共有函数即可。
所以下面介绍的是如何封装成共有的类来进行调用:
(这里主要是利用PointerPressed,PointerMoved,PointerReleased三个方法)
1.首先是XAML代码,页面布局只要放一个canvas,再在canvas下放一个rectangle
<Page x:Class="DragDemo.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:DragDemo" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid> <Canvas Width="300" Height="300" Background="White"> <Rectangle x:Name="rect" Width="100" Height="100" Fill="Coral"/> </Canvas> </Grid> </Page>
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices.WindowsRuntime; using Windows.Foundation; using Windows.Foundation.Collections; using Windows.UI.Popups; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Navigation; // “空白页”项模板在 http://go.microsoft.com/fwlink/?LinkId=391641 上有介绍 namespace DragDemo { /// <summary> /// 可用于自身或导航至 Frame 内部的空白页。 /// </summary> public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); this.NavigationCacheMode = NavigationCacheMode.Required; this.Loaded += MainPage_Loaded; } void MainPage_Loaded(object sender, RoutedEventArgs e) { DragHelper.Dragable(rect); } /// <summary> /// 在此页将要在 Frame 中显示时进行调用。 /// </summary> /// <param name="e">描述如何访问此页的事件数据。 /// 此参数通常用于配置页。</param> protected override void OnNavigatedTo(NavigationEventArgs e) { // TODO: 准备此处显示的页面。 // TODO: 如果您的应用程序包含多个页面,请确保 // 通过注册以下事件来处理硬件“后退”按钮: // Windows.Phone.UI.Input.HardwareButtons.BackPressed 事件。 // 如果使用由某些模板提供的 NavigationHelper, // 则系统会为您处理该事件。 } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Windows.Foundation; using Windows.UI.Popups; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Media; namespace DragDemo { public static class DragHelper { public static readonly DependencyProperty IsDraggingProperty = DependencyProperty.RegisterAttached( "IsDragging", typeof(bool), typeof(DragHelper), new PropertyMetadata(false)); public static readonly DependencyProperty StartLeftProperty = DependencyProperty.RegisterAttached("StartLeft", typeof(double), typeof(DragHelper), new PropertyMetadata(0.0d)); public static readonly DependencyProperty StartTopProperty = DependencyProperty.RegisterAttached("StartTop", typeof(double), typeof(DragHelper), new PropertyMetadata(0.0d)); public static readonly DependencyProperty StartPositionProperty = DependencyProperty.RegisterAttached("StartPosition", typeof(Point), typeof(DragHelper), new PropertyMetadata(default(Point))); public static bool Dragable(this UIElement control) { if (control == null) { throw new ArgumentNullException("control"); } if (VisualTreeHelper.GetParent(control) is Canvas) { control.PointerPressed += (sender, e) => { control.SetValue(IsDraggingProperty, true); control.SetValue(StartLeftProperty, Canvas.GetLeft(control)); control.SetValue(StartTopProperty, Canvas.GetTop(control)); control.SetValue(StartPositionProperty, e.GetCurrentPoint(null).Position); }; var coreWindow = Window.Current.CoreWindow; coreWindow.PointerMoved += (sender, args) => { if ((bool)control.GetValue(IsDraggingProperty)) { var currentPosition = args.CurrentPoint.Position; var startPosition = (Point)control.GetValue(StartPositionProperty); var deltaX = currentPosition.X - startPosition.X; var deltaY = currentPosition.Y - startPosition.Y; var startLeft = (double)control.GetValue(StartLeftProperty); var startTop = (double)control.GetValue(StartTopProperty); Canvas.SetLeft(control, startLeft + deltaX); Canvas.SetTop(control, startTop + deltaY); } }; coreWindow.PointerReleased += (sender, args) => control.SetValue(IsDraggingProperty, false); return true; } else { return false; } } } }
上述过程中,我遇到一个问题,我直接在MainPage构造函数中直接调用共通函数,然后就会报错。后来我想因为在
其中使用到VisualTreeHelper.GetParent(UIElement...),通过可视化树操作获取需要拖拉控件的父元素,但是一旦
页面还未加载完成就去获取当然应该会出错。所以我之后在页面的load事件里才去调用共通函数,这下应该就不会出
错了。
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:windows phone 8.1 实现元素拖曳效果 pointerpressed visualtreehelper pointermoved
原文地址:http://blog.csdn.net/u010792238/article/details/46756757