【Silverlight】Bing Maps开发应用与技巧五:实现图钉(Pushpin)的可拖放性(Draggable)扩展

简介:
 目前在Bing Maps Silverlight Control中并没有提供可拖放的图钉(Pushpin)控件,其强大、灵活的架构设计为开发者提供了非常强大的扩展支持,要实现图钉控件的可拖放性可以自己动手进行扩展实现。
System.Object 
   System.Windows.DependencyObject 
     System.Windows.UIElement 
       System.Windows.FrameworkElement 
         System.Windows.Controls.Control 
           System.Windows.Controls.ContentControl 
            Microsoft.Maps.MapControl.Pushpin
 
  在扩展Pushpin之前先了解下Pushpin控件在Bing Maps Silverlight Control中的结构设计(如上代码结构),Pushpin是通过扩展Silverlight中的ContentControl控件开发而成,并加入了了定位坐标(Location)属性及其它相关的属性、字段。鉴于图钉的定位主要会用到Location属性,故本篇只提出此属性,其他的字段属性的详细在后续的相关博文里介绍。
 
  在使用Bing Maps Silverlight Control开发中,使用内置提供的图钉(不提供可拖放操作功能)主要有两种方式,分别是后台代码动态创建后作为子对象添加到MapLayer上,另外一种方式则是直接在XAML代码里直接配置。如下代码块:
< m:Map  x:Name ="myMap"  Margin ="0,0,0,0"  CredentialsProvider =" {StaticResource MyCredentials} " >
  <m:MapLayer x:Name="MapLayer">    
    
< m:Pushpin  Location ="29.5076372217973, 106.489384971208"  Content ="D" ></ m:Pushpin >
 </m:MapLayer>
</ m:Map >
 
  通过上代码段的结构很清晰的知道,图钉控件(Pushpin)的父节点为MapLayer对象,在MapLayer中有一个属性ParentMap可以得到当前MapLayer对象属于那一个Map控件对象,于是在图钉对象上既然能够获取到直接所属的Map控件,也就是说在图钉控件里是可以对Map控件进行动态控制的。
 
  接下来就通过自定义一个可拖拽的图钉类来对Bing Maps Silverlight Control中内置的图钉控件进行扩展,可以通过如下的代码来实现一个最基本的可拖放的图钉的结构。
public   class  DraggablePushpin : Microsoft.Maps.MapControl.Pushpin
{
    
///   <summary>
    
///  是否正在拖放
    
///   </summary>
     private   bool  IsDragging  =   false ;
    
///   <summary>
    
///  鼠标拖放
    
///   </summary>
     private  EventHandler < MapMouseDragEventArgs >  MapMouseDragHandler;
    
///   <summary>
    
///  鼠标左键弹起
    
///   </summary>
     private  MouseButtonEventHandler MapMouseLeftButtonUpHandler;
    
///   <summary>
    
///  鼠标移动
    
///   </summary>
     private  MouseEventHandler MapMouseMoveHandler;
}
 
   实际上要实现一个对象的可拖拽是非常简单的,不清楚的可以访问我的另一篇博文《 Silverlight & Blend动画设计系列八:拖放(Drag-Drop)操作与拖放行为(DragBehavior)》进行了解。简单的说实现拖放操作就是通过鼠标事件动态改变对象的位置,只不过在Bing Maps Silverlight Control中要实现图钉控件的操作不能像传统的实现元素对象的操作那么去处理,这主要是由于地图控件(Map)中做了一些相关的处理的原因。
 
  鉴于这种种原因就不得不实现对象本身的行为特性的功能转移到Map控件的事件处理函数中去实现,Bing Maps Silverlight Control中的Map控件有一个名为MousePan的事件,专门用来处理鼠标拖放操作行为,其定义为如下结构:
[ScriptableMemberAttribute] 
public   override   event  EventHandler < MapMouseDragEventArgs >  MousePan;
 
  另外还有一个事件就是MouseMove,它被定义为Bing Maps Silverlignt Control中的Map控件的事件,专门用来处理鼠标移动的相关操作行为,其功能作用非常强大。
// 地图控件的鼠标移动事件定义
public   abstract   event  MouseEventHandler MouseMove;
 
  有了以上两个事件的支持我们的自定义可拖放的图钉控件就可以面世出生了。下面为完整的可拖放图钉控件的代码:
///   <summary>
///  功能描述:自定义扩展图钉类,实现可拖拽图钉。
///  编    写:Beniao
///  时    间:2010年5月31日22:37:46
///   </summary>
public   class  DraggablePushpin : Microsoft.Maps.MapControl.Pushpin
{
    
///   <summary>
    
///  是否正在拖放
    
///   </summary>
     private   bool  IsDragging  =   false ;
    
///   <summary>
    
///  鼠标拖放
    
///   </summary>
     private  EventHandler < MapMouseDragEventArgs >  MapMouseDragHandler;
    
///   <summary>
    
///  鼠标左键弹起
    
///   </summary>
     private  MouseButtonEventHandler MapMouseLeftButtonUpHandler;
    
///   <summary>
    
///  鼠标移动
    
///   </summary>
     private  MouseEventHandler MapMouseMoveHandler;

    
protected   override   void  OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
        
// 因为图钉是添加在MapLayer上的
        var parentLayer  =   this .Parent  as  MapLayer;
        
if  (parentLayer  !=   null )
        {
            
// MapLayer是Map的一个子对象
            var parentMap  =  parentLayer.ParentMap;
            
if  (parentMap  !=   null )
            {
                
if  ( this .MapMouseDragHandler  ==   null
                {
                    
this .MapMouseDragHandler  =   new  EventHandler < MapMouseDragEventArgs > (ParnetMap_MousePan);
                    parentMap.MousePan 
+=   this .MapMouseDragHandler;
                }

                
if  ( this .MapMouseLeftButtonUpHandler  ==   null )
                {
                    
this .MapMouseLeftButtonUpHandler  =   new  MouseButtonEventHandler(PrentMap_MouseLeftButtonUp);
                    parentMap.MouseLeftButtonUp 
+=   this .MapMouseLeftButtonUpHandler;
                }

                
if  ( this .MapMouseMoveHandler  ==   null )
                {
                    
this .MapMouseMoveHandler  =   new  MouseEventHandler(PrentMap_MouseMove);
                    parentMap.MouseMove 
+=   this .MapMouseMoveHandler;
                }
            }
        }
        
this .IsDragging  =   true ;

        
base .OnMouseLeftButtonDown(e);
    }

    
private   void  ParnetMap_MousePan( object  sender, MapMouseDragEventArgs e)
    {
        
if  ( this .IsDragging)
        {
            e.Handled 
=   true ;
        }
    }

    
private   void  PrentMap_MouseLeftButtonUp( object  sender, MouseButtonEventArgs e)
    {
        
this .IsDragging  =   false ;
    }

    
private   void  PrentMap_MouseMove( object  sender, MouseEventArgs e)
    {
        var map 
=  sender  as  Map;
        
if  ( this .IsDragging)
        {
            var mousePosition 
=  e.GetPosition(map);
            var geoPosition 
=  map.ViewportPointToLocation(mousePosition);
       //重新定位图钉位置
            
this .Location  =  geoPosition;
        }
    }
}
 
   通过扩展后的图钉控件(DraggablePushpin)就是一个完整的可支持鼠标拖放的图钉控件,其使用和内置的原始控件一样简单,如下代码实现了动态添加500个图钉在MapLayer上。
private   void  AddPushPin()
{
    
for  ( int  i  =   1 ; i  <   501 ; i ++ )
    {
        MapLayer.AddChild(
new  DraggablePushpin() 
        { 
           Content  =  i.ToString() 
        }, 
            new  Location(i  /   4 , i  /   2 )
        );
    }
}
 




本文转自 beniao 51CTO博客,原文链接:http://blog.51cto.com/beniao/326243,如需转载请自行联系原作者

目录
相关文章
Silverlight & Blend动画设计系列八:拖放(Drag-Drop)操作与拖放行为(DragBehavior)
原文:Silverlight & Blend动画设计系列八:拖放(Drag-Drop)操作与拖放行为(DragBehavior)   在Silverlight中自身并没有提供拖放功能的相关实现,要实现拖放功能得借助其事件支持(MouseLeftButtonDown、MouseLeftButtonUp和MouseMove)来完成,实际应用中我们可以通过行为(Behavior)特性将拖放操作封装为行为,这样可达到代码复用的效果。
1045 0

热门文章

最新文章