当前位置: 首页 > news >正文

【Silverlight】Bing Maps开发应用与技巧二:自定义图钉标注控件和动态ToolPanel

  在Bing Maps Silverlight Control中以及为我们提供了地图图钉控件Pushpin,我曾经在《使用图钉层(Pushpin layer)及地图图层(MapLayer)》一文中介绍过他的使用方法,本篇主要介绍如何自定义图钉标注控件以及对他的一些扩展,比如实现图钉的动态ToolPanel。

  关于图钉的UI外观的设计这里就不详细介绍了,通过Blend可以快速的构建UI界面。首先介绍下我的实现思想,通过Path构建图钉标注控件的UI外观,控件整体布局使用Grid布局,分别在Grid容器里设计好图钉UI外观效果和需要动态提示的ToolPanel(使用Border布局设计),默认将ToolPanel隐藏,在后台代码中通过鼠标事件进行控制其是否出现;另外还布局了一个TextBlock控件,用于出现图钉标注上的内容。下面是定义好的图钉风格的样式:

自定义图钉样式
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> < Style x:Name ="PushpinStyle" TargetType ="Controls:PushPinControl" >
< Setter Property ="Template" >
< Setter.Value >
< ControlTemplate TargetType ="Controls:PushPinControl" >
< Grid x:Name ="grdRoot" Height ="Auto" Width ="Auto" HorizontalAlignment ="Stretch" RenderTransformOrigin ="0,0" >
< Grid.RenderTransform >
< TransformGroup >
< ScaleTransform x:Name ="_ScaleTransform" ScaleX ="1" ScaleY ="1" />
< SkewTransform />
< RotateTransform />
< TranslateTransform />
</ TransformGroup >
</ Grid.RenderTransform >
< Path Stretch ="Fill" Opacity ="1" RenderTransformOrigin ="0.501,0.281" Data ="M0,-250L6.09909264359567,
-250C7.86508433137037,-249.8836797576689.5771753004554,-249.69696814830411.2361413649071,
-249.45760340507224.5078612249376,-247.54267687706734.3794798686271,
-242.25790788761241.2465583494687,-237.28331918533744.6800986937064,
-234.79602021988547.3625022581612,-232.38626737412349.3432151487858,
-230.51405973252250.3335754087938,-229.57795400437351.1485091856508,
-228.77623624619551.7942001036199,-228.16640729722156.0964631917223,
-224.10309778972868.1963801884179,-208.30943563495469.289336364603,
-191.49242467700570.6231971699074,-170.96846093138168.290878635012,
-158.51957608508459.6252929380878,-143.4629561406552.4136905999628,
-130.93264105652238.9633656169578,-121.17255818954525.9663459471247,
-99.975666711949622.717070324265,-94.676373334781919.5096780307535,
-85.853512255955416.5262691191198,-75.600224207054915.0345529933047,
-70.473516113063613.5988258504601,-64.989171709428512.2418500593682,
-59.40878743946698.8494006958964,-45.45784386714030.658368923825747,
-0.2648305226970930.658368923825747,-0.264830522697093L0.658368923825747,
-0.264830522697093C0.658368923825747,-0.264830522697093-6.20713033738298,
-39.8775058725022-10.9565428086754,-59.4087721806768-13.6705143479304,
-70.5696227914182-16.6994467050881,-81.3462113972954-19.8613212892067,
-89.645756433626-21.4422436994774,-93.7955199281247-23.0564059677924,
-97.3260283129902-24.6810425111283,-99.9756667119496-37.6780541099905,
-121.172569912188-51.1284623692131,-130.932797619228-58.3399704286158,
-143.462940881861-67.0055167526496,-158.519492415143-69.3378901087436,
-170.968446571251-68.0040291139176,-191.492413232913-66.9110789415046,
-208.309331812531-54.8111481537909,-224.103105568266-50.508885223533,
-228.166399667826-47.9261288596012,-230.605716191039-42.6354741589363,
-236.115224319832-34.2414024659624,-241.014917085726-30.0443655550756,
-243.464752007233-25.0714708225116,-245.762135285075-19.2732761689687,
-247.447058389738-16.3741806336881,-248.289518545224-13.2687567063844,
-248.978864381863-9.95082648482475,-249.457595894886-8.29186423506778,
-249.6969603997-6.57977326598088,-249.883671889854-4.81378157820587,-250z"

StrokeThickness
="2.5" Margin ="-28.398,-30.999,0,0" Width ="35" Height ="30.754" VerticalAlignment ="Top"
Fill
="#59000000" HorizontalAlignment ="Left" d:LayoutOverrides ="Width,Height" IsHitTestVisible ="False" >
< Path.RenderTransform >
< TransformGroup >
< ScaleTransform ScaleX ="1" ScaleY ="1" />
< SkewTransform AngleX ="-57.547" AngleY ="0" />
< RotateTransform Angle ="0" />
< TranslateTransform X ="45.252" Y ="0" />
</ TransformGroup >
</ Path.RenderTransform >
</ Path >
< Path Stretch ="Fill" Stroke ="#FF000000" Opacity ="1" RenderTransformOrigin ="0.501,0.281"
Data
="M0,-250L6.09909264359567,-250C7.86508433137037,-249.8836797576689.5771753004554,
-249.69696814830411.2361413649071,-249.45760340507224.5078612249376,
-247.54267687706734.3794798686271,-242.25790788761241.2465583494687,
-237.28331918533744.6800986937064,-234.79602021988547.3625022581612,
-232.38626737412349.3432151487858,-230.51405973252250.3335754087938,
-229.57795400437351.1485091856508,-228.77623624619551.7942001036199,
-228.16640729722156.0964631917223,-224.10309778972868.1963801884179,
-208.30943563495469.289336364603,-191.49242467700570.6231971699074,
-170.96846093138168.290878635012,-158.51957608508459.6252929380878,
-143.4629561406552.4136905999628,-130.93264105652238.9633656169578,
-121.17255818954525.9663459471247,-99.975666711949622.717070324265,
-94.676373334781919.5096780307535,-85.853512255955416.5262691191198,
-75.600224207054915.0345529933047,-70.473516113063613.5988258504601,
-64.989171709428512.2418500593682,-59.40878743946698.8494006958964,
-45.45784386714030.658368923825747,-0.2648305226970930.658368923825747,
-0.264830522697093L0.658368923825747,-0.264830522697093C0.658368923825747,
-0.264830522697093-6.20713033738298,-39.8775058725022-10.9565428086754,
-59.4087721806768-13.6705143479304,-70.5696227914182-16.6994467050881,
-81.3462113972954-19.8613212892067,-89.645756433626-21.4422436994774,
-93.7955199281247-23.0564059677924,-97.3260283129902-24.6810425111283,
-99.9756667119496-37.6780541099905,-121.172569912188-51.1284623692131,
-130.932797619228-58.3399704286158,-143.462940881861-67.0055167526496,
-158.519492415143-69.3378901087436,-170.968446571251-68.0040291139176,
-191.492413232913-66.9110789415046,-208.309331812531-54.8111481537909,
-224.103105568266-50.508885223533,-228.166399667826-47.9261288596012,
-230.605716191039-42.6354741589363,-236.115224319832-34.2414024659624,
-241.014917085726-30.0443655550756,-243.464752007233-25.0714708225116,
-245.762135285075-19.2732761689687,-247.447058389738-16.3741806336881,
-248.289518545224-13.2687567063844,-248.978864381863-9.95082648482475,
-249.457595894886-8.29186423506778,-249.6969603997-6.57977326598088,
-249.883671889854-4.81378157820587,-250z"

StrokeThickness
="2.5" HorizontalAlignment ="Left" Margin ="-18,-63.25,0,0" x:Name ="shpPushpin"
Width
="35" d:LayoutOverrides ="Width" Height ="63"
VerticalAlignment
="Top" Cursor ="Hand" >
< Path.RenderTransform >
< TransformGroup >
< ScaleTransform ScaleX ="1" ScaleY ="1" />
< SkewTransform AngleX ="0" AngleY ="0" />
< RotateTransform Angle ="0" />
< TranslateTransform X ="0" Y ="0" />
</ TransformGroup >
</ Path.RenderTransform >
< Path.Fill >
< LinearGradientBrush EndPoint ="0.5,1" StartPoint ="0.5,0" >
< GradientStop Color ="#FFFFF77F" Offset ="0" />
< GradientStop Color ="#FFFCF14E" Offset ="1" />
</ LinearGradientBrush >
</ Path.Fill >
</ Path >
< TextBlock TextWrapping ="Wrap" d:LayoutOverrides ="Height,GridBox" RenderTransformOrigin ="0.51,0.491" VerticalAlignment ="Top"
TextAlignment
="Center" Margin ="-15.55,-60,0,0" x:Name ="txtTitle"
Width
="30" FontSize ="24" Visibility ="Visible" FontFamily ="Verdana" HorizontalAlignment ="Left" IsHitTestVisible ="False" >
< TextBlock.RenderTransform >
< TransformGroup >
< ScaleTransform />
< SkewTransform AngleX ="0" AngleY ="0" />
< RotateTransform Angle ="0" />
< TranslateTransform X ="0" Y ="0" />
</ TransformGroup >
</ TextBlock.RenderTransform >
</ TextBlock >
< Border x:Name ="ToolPanel" VerticalAlignment ="Stretch" Background ="#A82D2D2D" CornerRadius ="8,8,8,8" Visibility ="Collapsed"
BorderBrush
="#FF626262" BorderThickness ="2,2,2,2" ScrollViewer.HorizontalScrollBarVisibility ="Visible"
RenderTransformOrigin
="0.5,0.5" Grid.Row ="0" Width ="300" Height ="200" >
< Border.RenderTransform >
< TransformGroup >
< ScaleTransform />
< SkewTransform />
< RotateTransform />
< TranslateTransform X ="20" Y ="-75" />
</ TransformGroup >
</ Border.RenderTransform >
< StackPanel VerticalAlignment ="Top" Margin ="5,10,5,10" >
< Grid Height ="29" VerticalAlignment ="Top" >
< TextBlock Height ="25" Width ="346" Text ="标题内容" TextWrapping ="Wrap" Foreground ="#FFF0E7E7" FontSize ="16"
HorizontalAlignment
="Left" Margin ="12,3,0,1" />
</ Grid >
< StackPanel VerticalAlignment ="Top" >
< Border x:Name ="ContentBorder" Background ="#FF000000" CornerRadius ="8,8,8,8" VerticalAlignment ="Top"
Margin
="0,3,0,3" Padding ="0,8,0,8" Opacity ="0.68" MinHeight ="200" >
< TextBlock Text ="显示内容" Foreground ="White" Margin ="3" ></ TextBlock >
</ Border >
</ StackPanel >
</ StackPanel >
</ Border >
</ Grid >
</ ControlTemplate >
</ Setter.Value >
</ Setter >
</ Style >

  接下来要做的就是实现图标注控件的定义以及动态控制ToolPanel控件的显示与否了,主要思路就是通过引用上面定义的样式,以模板的方式从样式里获取到相应的控件元素进行动态控制,详细见如下代码:

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> /// <summary>
/// 自定义图钉控件
/// </summary>
public class PushPinControl:ContentControl
{
private string Text;

public PushPinControl(Stringtext)
{
// 设置图钉标注控件的标注内容
this .Text = text == "" ? " M " :text;
DefaultStyleKey
= typeof (PushPinControl);
// 为当前对象引用样式,从全局资源里读取
this .Style = Application.Current.Resources[ " PushpinStyle " ] as Style;
}

public override void OnApplyTemplate()
{
base .OnApplyTemplate();

// 从样式模板中获取TextBlock控件
vartextBlock = GetTemplateChild( " txtTitle " ) as TextBlock;
textBlock.Text
= this .Text;
// 从样式模板中获取ToolPanel(既Border布局实现的,详细见样式的定义)控件
varToolPanelBorder = GetTemplateChild( " ToolPanel " ) as Border;
// 通过事件动态控制ToolPanel的显示和隐藏
this .MouseEnter += (mes,meo) => {ToolPanelBorder.Visibility = Visibility.Visible;};
this .MouseLeave += (mls,mlo) => {ToolPanelBorder.Visibility = Visibility.Collapsed;};
}
}

       

  到这里就成功的完成了图钉标注控件的自定义了,接下来看看如何使用这个自定义的图钉标注控件,详见如下代码块:

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> private void AddPushPin()
{
// 添加BingMapsSilverlightControl自带的图钉
// varpushpin=newPushpin();
// pushpin.Location=newLocation(29.5076372217973,106.489384971208);
// 添加自定义的图钉
varpushpin = new PushPinControl( " D " );
MapLayer.AddChild(pushpin,
new Location( 29.5076372217973 , 106.489384971208 ));
}

       

  或许会有人问道,如何动态的实现ToolPanel里显示的内容?要实现这个功能也是非常简单的,首先我们来分析下上面定义的样式里对ToolPanel部分的定义:

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> < Border x:Name ="ToolPanel" VerticalAlignment ="Stretch" Background ="#A82D2D2D" CornerRadius ="8,8,8,8" Visibility ="Collapsed"
BorderBrush
="#FF626262" BorderThickness ="2,2,2,2" ScrollViewer.HorizontalScrollBarVisibility ="Visible"
RenderTransformOrigin
="0.5,0.5" Grid.Row ="0" Width ="300" Height ="200" >
< Border.RenderTransform >
< TransformGroup >
< ScaleTransform />
< SkewTransform />
< RotateTransform />
< TranslateTransform X ="20" Y ="-75" />
</ TransformGroup >
</ Border.RenderTransform >
< StackPanel VerticalAlignment ="Top" Margin ="5,10,5,10" >
< Grid Height ="29" VerticalAlignment ="Top" >
< TextBlock Height ="25" Width ="346" Text ="标题内容" TextWrapping ="Wrap" Foreground ="#FFF0E7E7" FontSize ="16"
HorizontalAlignment
="Left" Margin ="12,3,0,1" />
</ Grid >
< StackPanel VerticalAlignment ="Top" >
< Border x:Name ="ContentBorder" Background ="#FF000000" CornerRadius ="8,8,8,8" VerticalAlignment ="Top"
Margin
="0,3,0,3" Padding ="0,8,0,8" Opacity ="0.68" MinHeight ="200" >
< TextBlock Text ="显示内容" Foreground ="White" Margin ="3" ></ TextBlock >
</ Border >
</ StackPanel >
</ StackPanel >
</ Border >

  使用了Border进行圆角布局,在其内部通过StackPanel垂直布局实现了ToolPanel的的标题和内容两大部分,内容部分并通过Border进行设计,取名为ContentBorder,这是为了实现动态呈现显示内容而设计,整体Border通过TranslateTransform进行一个偏移的处理,也就是让ToolPanel始终显示在图钉标注的右边相应的位置,详细见本文前面提供的截图。

  从上面的实现知道ToolPanel是在鼠标的MouseEnter事件执行的时候才会显示的,当鼠标离开就会将其可见性设置为隐藏。了解了这个原理后就可以想到,是否可以从MouseEnter事件中通过某种方法去处理?事件是个非常强大的技术点,这里我们就可以通过事件,将显示内容的Border容器派发处理,通过事件的监听来动态更新其显示内容。首先需要扩展一个事件类:

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> public delegate void PushpinContentChangedHandler( object sender,PushpinContentChangedEvantAgrse);

public class PushpinContentChangedEvantAgrs:EventArgs
{
public BorderContentBorder{ get ; set ;}

public PushpinContentChangedEvantAgrs(){}

public PushpinContentChangedEvantAgrs(BorderContentBorder)
{
this .ContentBorder = ContentBorder;
}
}

接下来为自定义的图钉标注类定义一个事件,事件类型就为上面所定义好的委托类型,传递的事件为PushpinContentChangedEventArgs.

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> /// <summary>
/// 自定义图钉控件
/// </summary>
public class PushPinControl:ContentControl
{
public event PushpinContentChangedHandlerContentChangedEvent;

现在需要做的就是在当前对象的MouseEnter事件中去触发这个事件,将样式里所定义好的用于显示内容的Border对象获取出来,通过事件参数传递派发出去,让事件监听段可以通过该事件获取事件参数进行ToolPanel内容的呈现更新。所有我们需要改写PushPinControl的OnApplyTemplate方法:

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> public override void OnApplyTemplate()
{
base .OnApplyTemplate();

// 从样式模板中获取TextBlock控件
vartextBlock = GetTemplateChild( " txtTitle " ) as TextBlock;
textBlock.Text
= this .Text;
// 从样式模板中获取ToolPanel(既Border布局实现的,详细见样式的定义)控件
varToolPanelBorder = GetTemplateChild( " ToolPanel " ) as Border;
// 获取内容Border对象,通过事件将该对象派发出去,在使用段可以通过监听这个事件而获取到内容Border
varContentBorder = GetTemplateChild( " ContentBorder " ) as Border;
// 通过事件动态控制ToolPanel的显示和隐藏
this .MouseEnter += (mes,meo) =>
{
ToolPanelBorder.Visibility
= Visibility.Visible;
if (ContentChangedEvent != null )
{
ContentChangedEvent(
this , new PushpinContentChangedEvantAgrs(ContentBorder));
}
};
this .MouseLeave += (mls,mlo) => {ToolPanelBorder.Visibility = Visibility.Collapsed;};
}

  通过ContentChangedEvent事件的监听动态的去改变ToolPanel里的显示内容就可以达到我们的目的了,比如我们动态的将ToolPanel里的显示内容更改为一张图片,上面使用自定义图钉标注的代码将变成下面这样的。

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> private void AddPushPin()
{
// 添加BingMapsSilverlightControl自带的图钉
// varpushpin=newPushpin();
// pushpin.Location=newLocation(29.5076372217973,106.489384971208);
// 添加自定义的图钉
varpushpin = new PushPinControl( " D " );
pushpin.ContentChangedEvent
+= (sender,o) =>
{
// 构造Image对象用于显示在ToolPanel中
varimage = new Image{Width = 100 ,Height = 100 ,Margin = new Thickness( 8 )};
image.Source
= new BitmapImage( new Uri( " Resources/Smbecker.png " ,UriKind.RelativeOrAbsolute));
Borderborder
= o.ContentBorder;

border.Child
= image;
};
MapLayer.AddChild(pushpin,
new Location( 29.5076372217973 , 106.489384971208 ));
}

        

  之前有网友问到如何实现可拖拽的图钉标注控件,鉴于篇幅的原因这里就不做介绍,不清楚的朋友可以留言讨论。本篇就介绍到这里,欢迎大家前来交流、讨论、拍砖。

  更多学习资料:

  MSDN:http://msdn.microsoft.com/en-us/library/ee681890.aspx

  官方:http://www.microsoft.com/maps

  中国Bing Maps:http://cn.bing.com/ditu/

  官方SDK:http://www.microsoft.com/maps/isdk/silverlight/

相关文章:

  • Agile Framework视频演示发布
  • 给你的VS2010换肤
  • TextBox里面换行的问题
  • 轻松话卷积
  • 挪威趣事
  • sqlserver 转 access 笔记
  • IE与COOKIE
  • 什么时候可以找回民族的自尊,不再崇洋媚外?--从华晨老总骏捷发布会的一番话说起...
  • 竞争网络权值分析
  • C# Tips Written By Andrew Troelsen
  • A Closer Look At Parallax Occlusion Mapping
  • 寻找最佳的数据存储方式
  • XMLHTTP资料
  • SQL两表匹配,将A表的指定字段所有内容根据条件更新B表指定字段的所有内容...
  • 齐祖神威
  • [deviceone开发]-do_Webview的基本示例
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 2019.2.20 c++ 知识梳理
  • Android Volley源码解析
  • Consul Config 使用Git做版本控制的实现
  • Docker 笔记(2):Dockerfile
  • ES6--对象的扩展
  • RxJS: 简单入门
  • Sass 快速入门教程
  • Vue UI框架库开发介绍
  • 产品三维模型在线预览
  • 从零搭建Koa2 Server
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 后端_MYSQL
  • 力扣(LeetCode)56
  • 每天一个设计模式之命令模式
  • 前端知识点整理(待续)
  • 在Docker Swarm上部署Apache Storm:第1部分
  • 扩展资源服务器解决oauth2 性能瓶颈
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • ​LeetCode解法汇总518. 零钱兑换 II
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • #{} 和 ${}区别
  • (javascript)再说document.body.scrollTop的使用问题
  • (八)光盘的挂载与解挂、挂载CentOS镜像、rpm安装软件详细学习笔记
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (图)IntelliTrace Tools 跟踪云端程序
  • (转)人的集合论——移山之道
  • ... 是什么 ?... 有什么用处?
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .net/c# memcached 获取所有缓存键(keys)
  • .NET/C# 将一个命令行参数字符串转换为命令行参数数组 args
  • .NET基础篇——反射的奥妙
  • .NET命名规范和开发约定
  • /etc/X11/xorg.conf 文件被误改后进不了图形化界面
  • ??eclipse的安装配置问题!??
  • @EnableAsync和@Async开始异步任务支持
  • @Repository 注解
  • [ NOI 2001 ] 食物链