Windows Phone 7 编程实践—捕获Map控件的DoubleTap事件
作品目标:Windows Phone 7 开发的实用手册
Windows Phone 7 编程实践--捕获Map控件的DoubleTap事件。
DoubleTap事件的放大功能需要下载新的地图信息,会给用户带来不小的流量负担,因此程序自主控制地图的缩放功能很有必要。
参考资料
目录
提出问题
MSDN中文论坛—Windows Phone 7开发上有位朋友提出想重载Map的默认的双击事件(Double Tap)。因为双击事件的放大功能需要下载新的地图信息,误操作会给用户带来不小的流量负担。从用户的角度来思考做出的程序,肯定会大受欢迎。
Microsoft.Phone.Controls.Maps.Map默认的双击(Double Tap)事件是修改Map的ZoomLevel属性。那么Map空间的双击(Double Tap)事件如何重载呢,让我们先看看MSDN上关于Map Event的帮助。
Map Members
Windows Phone
Name
|
Description
|
|
(Inherited from FrameworkElement.)
|
||
(Inherited from UIElement.)
|
||
(Inherited from Control.)
|
||
(Inherited from UIElement.)
|
||
(Inherited from UIElement.)
|
||
(Inherited from FrameworkElement.)
|
||
(Inherited from FrameworkElement.)
|
||
Occurs when there is an error loading the map. (Inherited from MapCore.)
|
||
(Inherited from UIElement.)
|
||
(Inherited from UIElement.)
|
||
(Inherited from UIElement.)
|
||
(Inherited from UIElement.)
|
||
(Inherited from UIElement.)
|
||
Occurs when the screen is touched and dragged to pan the map. This event occurs every frame. (Inherited from MapCore.)
|
||
Occurs when the map tiles are fully downloaded, regardless of whether the user is still interacting with the map. (Inherited from MapCore.)
|
||
Occurs when the map is touched to zoom the map. (Inherited from MapCore.)
|
||
Occurs when the map mode changes. (Inherited from MapCore.)
|
||
(Inherited from UIElement.)
|
||
(Inherited from UIElement.)
|
||
(Inherited from UIElement.)
|
||
(Inherited from UIElement.)
|
||
(Inherited from UIElement.)
|
||
(Inherited from UIElement.)
|
||
(Inherited from FrameworkElement.)
|
||
Occurs when the view towards which the map is animating changes. (Inherited from MapCore.)
|
||
(Inherited from FrameworkElement.)
|
||
Occurs when the view is done changing. (Inherited from MapCore.)
|
||
Occurs for every frame of a view change. (Inherited from MapCore.)
|
||
Occurs when the view starts changing. (Inherited from MapCore.)
|
显然,在这里我们找不到关于双击(Double Tap)事件,只能靠我们自己捕获触控手势。
分析问题
依据原有经验,重载OnManipulationStarted方法
依据已有的Silverlight多点触控的经验,在MainPage类中重载OnManipulationStarted处理对于Map的触控。
首先判断触控的来源于Map的话,再去判断是否是双击手势。
protected override void OnManipulationStarted(ManipulationStartedEventArgs args)
{
if (args.OriginalSource == myMap)//myMap是定义的map的name
{
//判断手势,如果是doubleTap则处理
//Silverlight对于手势的判断,有文章专门说明Silverlight应用XNA的手势判断
//……
}
args.Complete();
base.OnManipulationStarted(args);
}
尝试发现DoubleTap触控让Map拦截处理,并没有传入OnManipulationStarted方法中。
想到如果在Map的上层添加一个透明的Button,Button的作用就是截获所有map的触控。这样做虽然达到了阻止DoubleTap事件的处理,但是缺点视乎更难以接受,放弃了所有Map自带的功能,Map的所有功能都要自己实现。
看来此路不通,那我们换一种思路,从触控手势入手,判断TouchTap的手势方法中寻找曙光。
从触控手势入手,判断TouchTap的手势方法中寻找曙光
Charles Petzold有篇文章Touch Gestures on Windows Phone介绍了Silverlight在Windows Phone中判断触控手势,文章中介绍了捕获12种手势(GestureBegin, GestureCompleted, Tap, DoubleTap, Hold, DragStarted, DragDelta, DragCompleted, Flick, PinchStarted, PinchDelta, PinchCompleted)的方法。
具体做法就是在XAML文件中做如下声明:
<Grid ... >
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener
Tap="OnGestureListenerTap"
</toolkit:GestureService.GestureListener>
...
</Grid>
然后在构造函数中增加GestureListener.
GestureListener gestureListener =
GestureService.GetGestureListener(element);
gestureListener.DoubleTap += OnGestureListenerTap;
如法炮制,我们将大牛Charles Petzold的方法应用于对于Map的控制上。
解决问题
在MainPage.XAML中添加Canvas和toolkit:GestureService.GestureListener
<Canvas x:Name="LayoutRoot" Background="Transparent">
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener DoubleTap="GestureListener_DoubleTap"/>
</toolkit:GestureService.GestureListener>
</Canvas>
添加Map控件,设置属性
在Canvas中添加代码如下,
<my:Map Name="MyMap"
ScaleVisibility="Collapsed"
IsEnabled="True"
Height="800" Width="480"
CopyrightVisibility="Collapsed"
MapZoom="MyMap_MapZoom">
</my:Map>
Map控件最终在XAML中的效果如图1.
图1 Map控件最终在XAML中的效果
在MainPage类中GestureListener_DoubleTap处理代码
private void GestureListener_DoubleTap(object sender, GestureEventArgs e)
{
{
MessageBox.Show(string.Format("DoubleTap Occurred Here: {0}",
e.GetPosition(null).ToString()));
e.GetPosition(null).ToString()));
}
Debug调试
在GestureListener_DoubleTap中设置断点,双击map地图,代码乖乖的执行到GestureListener_DoubleTap方法中
按F5继续执行,还可以听到手指触控的声音,终于等到奇妙的声音了,画面显示DoubleTap触控的坐标。OK,完成的喜悦溢于言表。
如果这个对您也有用,请下载代码:https://files.cnblogs.com/xuesong/MapDoubleTap.zip