UWP——ManipulationDelta?蛤?

首先声明:我知识水平不高,裤腰带也不高,所以有些东西我也不是很精确。来出现了偏差,我不想要负白不民白啊?

大家吼蛙!这几天我在一个群里看到一个人问:如何拖动(钦定)一个UWP控件,使其移动呢?当时我就念两首诗:苟…………如果单独使用Canvas + PointerPressed + PointerMoved + PointerReleased,会导致需要用三个Event Handler,这样会使程序运行江化。

另一种情景是:我想要让我的UWP识别手势操作:比如向右滑动200个像素就打开汉堡菜单,怎么办?

针对这两种情景,坠吼的解决方法是使用ManipulationDelta。要记住,ManipulationDelta是一个事件,并且这个事件是放在要被操作的东西上面的。

现在我们有一个空白的MainPage,我们要无中生有弄出一些东西来。把原来的Grid换成Canvas(只有用Canvas才能精确控制一个东西在哪一个像素点上),加入一个按钮,并实现ManipulationDelta事件。现在的MainPage.xaml应该是这样的:

<Page x:Class="ManipulationDeltaDemo.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:ManipulationDeltaDemo" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d">
	<Canvas x:Name="MyCanvas">
		<Button x:Name="Btn" Content="Drag Me!" ManipulationDelta="Btn_ManipulationDelta"/>
	</Canvas>
</Page>

现在我们要钦定我们的Btn要接收哪几种的手势、拖动。这个使用ManipulationMode实现。既然我们的按钮要拖动,那么肯定是要在x轴和y轴都要接收操作。所以我们在MainPage的构造方法里(或OnNavigatedTo重载方法里)写上下列代码:

public MainPage(){
	this.InitializeComponent();
	Btn.ManipulationMode = ManipulationModes.TranslateY | ManipulationModes.TranslateX;
}

这样就指定了Btn要接收什么类型的操作。现在,我们要真正实现拖动的部分了。我们在Btn_ManipulationDelta(object, ManipulationDeltaRoutedEventArgs)方法写入下列代码:

double moveX = Canvas.GetLeft(Btn) + e.Delta.Translation.X;
double moveY = Canvas.GetTop(Btn) + e.Delta.Translation.Y;
Canvas.SetLeft(Btn, moveX);
Canvas.SetTop(Btn, moveY);

我们可以看出,这里实际上是将Btn所在的坐标向右(如果e.Delta.Translation.X < 0就是向左)移动我们x轴拖动的像素数量,向下/上移动我们y轴拖动的数量。 现在运行程序,能运行是能运行,也能拖动了,但是出现了一个问题:如果我们拖动过头了怎么办?这个Btn会直接消失,看不见找不回来了。为了避免这个,我们需要做一个判断(长者说过,接到这些消息,你们本身也要判断),判断是否在边界上。现在代码如下:

 double moveX = Canvas.GetLeft(Btn) + e.Delta.Translation.X; double moveY = Canvas.GetTop(Btn) + e.Delta.Translation.Y; if(moveX >= 0 && moveX <= MyCanvas.ActualWidth - Btn.ActualWidth) Canvas.SetLeft(Btn, moveX); if(moveY >= 0 && moveY <= MyCanvas.ActualHeight - Btn.ActualHeight)
Canvas.SetTop(Btn, moveY);

这样,这个Button就不会跑到窗口外面了。至于为什么要用ActualWidth和ActualHeight,我可以回答你一句无可奉告,因为我也不知道。

别忘了,此时这个Button还可以接收所有其他的事件。所以你还是可以点击按钮滴。吼蛙!

这个例子的源代码在这里

识得唔识得嘎?

Excited!

老梁

12/17/2016

Advertisements

发表评论

Fill in your details below or click an icon to log in:

WordPress.com 徽标

You are commenting using your WordPress.com account. Log Out /  更改 )

Google+ photo

You are commenting using your Google+ account. Log Out /  更改 )

Twitter picture

You are commenting using your Twitter account. Log Out /  更改 )

Facebook photo

You are commenting using your Facebook account. Log Out /  更改 )

Connecting to %s