ArcGIS API for Silverlight——小滑块

前两节的地图中,总感觉少点什么……对,就是一个sliderbar,有了它感觉就像汽车有了方向盘一样,能够控制方向了。那么来看看实现上面这个例子中的滑块条需要做什么工作吧。
在silverlight中创建一个UserControl,把上面sliderbar的外观和功能都封装在里面。
来看具体工作。vs中,在silverlight工程上右键单击,add,new item,选择silverlight user control,起名叫mapslider,在mapslider.xaml中填如下代码:
- <Grid x:Name="slidergrid" HorizontalAlignment="Left" VerticalAlignment="Center" Background="Azure" Margin="20">
- <StackPanel Orientation="Vertical">
- <Button x:Name="btnzoomin" Content="+" Click="btnzoomin_Click" />
- <Slider x:Name="sliderLOD" Orientation="Vertical" Height="200" SmallChange="1" LargeChange="1" Minimum="0" Cursor="Hand" ValueChanged="slider1_ValueChanged" />
- <Button x:Name="btnzoomout" Content="-" Click="btnzoomout_Click" />
- </StackPanel>
- </Grid>
复制代码
上面这些就是滑块条的外观,接下来看功能部分。大致思路是在mapslider类中设置一个公共属性Map,就是需要操作的地图了,但这个属性不是ESRI.ArcGIS.Map,而是另一个自定义类。为什么要这么做?因为这个自定义类需要实现INotifyPropertyChanged接口,当我们把自己的Map控件作为mapslider的属性赋值的时候,这个Map需要做另外一些工作。看代码吧,不太明白的话就要加强对silverlight中data binding的学习。在mapslider.xaml.cs页面中填入一下代码:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Documents;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Animation;
- using System.Windows.Shapes;
- using System.ComponentModel;
- namespace customcontrol
- {
- public partial class mapslider : UserControl
- {
- private mymap map = new mymap();
- public ESRI.ArcGIS.Map Map
- {
- get
- {
- return map.Map;
- }
- set
- {
- map.Map=value;
- if (map.Map != null)
- {
- Map.ExtentChanged += new EventHandler<ESRI.ArcGIS.ExtentEventArgs>(map_ExtentChanged);
- Map.SnapToLevels = true;
- ((ESRI.ArcGIS.ArcGISTiledMapServiceLayer)Map.Layers[0]).Initialized += new EventHandler<EventArgs>(layer0_initialized);
- }
- }
- }
- private void layer0_initialized(object o,EventArgs e)
- {
- sliderLOD.Maximum = ((ESRI.ArcGIS.ArcGISTiledMapServiceLayer)Map.Layers[0]).TileInfo.Lods.Length - 1;
- }
- public mapslider()
- {
- InitializeComponent();
- }
- private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
- {
- if (map.Map!=null)
- {
- Map.ZoomToResolution(((ESRI.ArcGIS.ArcGISTiledMapServiceLayer)Map.Layers[0]).TileInfo.Lods[Convert.ToInt32(e.NewValue)].Resolution);
- }
- }
- private void map_ExtentChanged(object o, ESRI.ArcGIS.ExtentEventArgs e)
- {
- ESRI.ArcGIS.ArcGISTiledMapServiceLayer layer = Map.Layers[0] as ESRI.ArcGIS.ArcGISTiledMapServiceLayer;
- int i;
- for (i = 0; i < layer.TileInfo.Lods.Length; i++)
- {
- if (Map.Resolution == layer.TileInfo.Lods[i].Resolution)
- break;
- }
- sliderLOD.Value = i;
- }
- private void btnzoomin_Click(object sender, RoutedEventArgs e)
- {
- sliderLOD.Value += 1;
- }
- private void btnzoomout_Click(object sender, RoutedEventArgs e)
- {
- sliderLOD.Value -= 1;
- }
- }
- //执行了这个接口后,当在主页面page.xaml.cs中给Map赋值的时候,就能返到set语句中,以便执行绑定事件的代码
- public class mymap:INotifyPropertyChanged
- {
- private ESRI.ArcGIS.Map map;
- public ESRI.ArcGIS.Map Map
- {
- get{return map;}
- set
- {
- map = value;
- if (PropertyChanged!=null)
- {
- PropertyChanged(this, new PropertyChangedEventArgs("Map"));
- }
- }
- }
- public event PropertyChangedEventHandler PropertyChanged;
- }
- }
复制代码
做完封装的工作,来看如何在page.xaml中使用这个控件。只需要三行代码:1、注册user control的命名空间(和对Silverlight API的引用是一样的,放在页面中的根元素UserControl里):
xmlns:uc="clr-namespace:customcontrol"
2、在页面中添加这个slider:
<Grid x:Name="LayoutRoot" Background="White">
<!--地图在这里-->
</esri:Map>
<uc:mapslider x:Name="mapslider1"/>
</Grid>
3、在初始化的时候对我们自定义控件的Map属性赋值(page.xaml.cs中):
public Page()
{
InitializeComponent();
mapslider1.Map = Map1;
}
到此应该有这个感觉,封装比较麻烦,但使用封装好的控件非常简便。这就是Widgets带给我们的好处。目前的beta版中,SilverlightAPI已经替我们完成5个Widgets的封装,它们分别是:Magnifier,ToolBar,BookMark,Navigation,MapTip,其中ToolBar内部使用了ToolBarItemCollection和ToolBarItem等类。还是通过一个例子,来看看这几个控件都长什么样吧(点击这里):

MapTip需要使用到Query Task,以后的小节中再涉及到。现在分别熟悉一下这几个Widgets的用法。
1、ToolBar和Magnifier:
这个和ADF开发中的ToolBar(工具条)是一样的,里面可以添加ToolItem(工具),已实现各种功能,比如平移,缩放等。silverlight中当然要有一些比较好看的效果了,比如把鼠标放在工具条上选择工具的时候,会有放大效果,这个效果是默认的,不能设置;点击一个工具时,该工具会跳动一下,这个是ToolbarItemClickEffect中的Bounce效果(目前只有Bounce和None两个选择),也是默认的。此例中ToolBar里面有三个ToolBarItem,分别是Pan,FullExtent和Magnifier(本身也是一个Widget),下面是ToolBar的布局:
- <Grid Height="110" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,10,10,0" >
- <Rectangle Fill="#22000000" RadiusX="10" RadiusY="10" Margin="0,4,0,0" />
- <Rectangle Fill="#775C90B2" Stroke="Gray" RadiusX="10" RadiusY="10" Margin="0,0,0,5" />
- <Rectangle Fill="#66FFFFFF" Stroke="DarkGray" RadiusX="5" RadiusY="5" Margin="10,10,10,15" />
- <StackPanel Orientation="Vertical">
- <esriWidgets:Toolbar x:Name="MyToolbar" MaxItemHeight="80" MaxItemWidth="80"
- VerticalAlignment="Top" HorizontalAlignment="Center"
- ToolbarItemClicked="MyToolbar_ToolbarItemClicked"
- ToolbarItemClickEffect="Bounce"
- Width="250" Height="80">
- <esriWidgets:Toolbar.Items>
- <esriWidgets:ToolbarItemCollection>
- <esriWidgets:ToolbarItem Text="Pan">
- <esriWidgets:ToolbarItem.Content>
- <Image Source="img/i_pan.png" Stretch="UniformToFill" Margin="5" />
- </esriWidgets:ToolbarItem.Content>
- </esriWidgets:ToolbarItem>
- <esriWidgets:ToolbarItem Text="Full Screen">
- <esriWidgets:ToolbarItem.Content>
- <Image Source="img/i_globe.png" Stretch="UniformToFill" Margin="5" />
- </esriWidgets:ToolbarItem.Content>
- </esriWidgets:ToolbarItem>
- <esriWidgets:ToolbarItem Text="Full Screen">
- <esriWidgets:ToolbarItem.Content>
- <Image Source="img/magglass.png" Stretch="UniformToFill" Margin="5"
- MouseLeftButtonDown="Image_MouseLeftButtonDown"/>
- </esriWidgets:ToolbarItem.Content>
- </esriWidgets:ToolbarItem>
- </esriWidgets:ToolbarItemCollection>
- </esriWidgets:Toolbar.Items>
- </esriWidgets:Toolbar>
- <TextBlock x:Name="StatusTextBlock" Text="" FontWeight="Bold" HorizontalAlignment="Center"/>
- </StackPanel>
- </Grid>
复制代码
然后是code-behind内容:
private void MyToolbar_ToolbarItemClicked(object sender, ESRI.ArcGIS.Widgets.SelectedToolbarItemArgs e)
{
switch (e.Index)
{
case 0:
//pan
break;
case 1:
Map1.ZoomTo(Map1.Layers.GetFullExtent());
break;
case 2:
break;
}
}
private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
MyMagnifier.Enabled = !MyMagnifier.Enabled;
}
别忘了在page的构造函数中加一句:MyMagnifier.Initialize(Map1);。可以看出,Pan工具不需要任何代码,因为地图本身的默认动作就是Pan,而FullExtent也是利用了Map的ZoomTo()。放大镜的工具是在该图片被鼠标左键按住的过程中激活的(设置enabled属性),只要鼠标左键没有按住放大镜图片,该Widget就设置为不可用。比较有用的是我们可以单独设置放大镜自己的图层及放大倍数,这里放大镜使用的就是StreetMap,倍数为3。
2、BookMark:
这个功能和ArcMap(9.3版本)中的BookMark是一样的,可以像看书一样,为当前地图范围设置一个书签,便于其他时候快速定位到该范围。而查看API中的Bookmark.MapBookmark类(可以利用它对书签的内容进行单个添加或删除),可以发现其实每个书签存储的内容是一个Extent,然后再起一个名字就可以了。添加了bookmark widget后似乎会造成vs中的preview窗口出错。
<!--bookmark-->
<Canvas>
<esriWidgets:Bookmark x:Name="MyBookmarks" Width="125" HorizontalAlignment="Left" VerticalAlignment="Top"
Margin="20" Background="#99257194" BorderBrush="#FF92a8b3" Foreground="Black"
Loaded="MyBookmarks_Loaded" />
</Canvas>
page.xaml.cs中:
private void MyBookmarks_Loaded(object sender, RoutedEventArgs e)
{
MyBookmarks.Map = Map1;
}
3、Navigation:
这个导航条工具是目前网络地图必备的一个控件,但silverlight的功能,可以轻易实现地图的旋转(其实也可以在代码中通过Map.Rotation属性来设置)。经试验这个widget只能放在StackPanel或Grid容器里,如果放在Canvas里的话地图中不会显示。
<!--navigation bar.must be in a stackpanel-->
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Bottom">
<esriWidgets:Navigation x:Name="MyNavigation" Margin="5" />
</StackPanel>
同样在page的构造函数中添加一句:MyNavigation.Map = Map1;。
API中的Widgets可以简化我们的工作,拿来即用。但明显的缺陷就是不灵活,如果想使自己的控件不那么千篇一律的话,就需要自己进行开发工作了。
ArcGIS API for Silverlight——小滑块的更多相关文章
- ArcGIS API for Silverlight开发入门
你用上3G手机了吗?你可能会说,我就是喜欢用nokia1100,ABCDEFG跟我 都没关系.但你不能否认3G是一种趋势,最终我们每个人都会被包裹在3G网络中.1100也不是一成不变,没准哪天为了打击 ...
- arcgis api for silverlight使用google map等多个在线地图
原文 http://blog.csdn.net/leesmn/article/details/6820245 无可否认,google map实在是很漂亮.可惜对于使用arcgis api for si ...
- ArcGIS api fo silverlight学习一(silverlight加载GeoServer发布的WMS地图)
最好的学习资料ArcGIS api fo silverlight官网:http://help.arcgis.com/en/webapi/silverlight/samples/start.htm 一. ...
- ArcGIS API for Silverlight动态标绘的实现
原文:ArcGIS API for Silverlight动态标绘的实现 1.下载2个dll文件,分别是: ArcGISPlotSilverlightAPI.dll 和 Matrix.dll 其下载地 ...
- ArcGIS API for Silverlight地图加载众多点时,使用Clusterer解决重叠问题
原文:ArcGIS API for Silverlight地图加载众多点时,使用Clusterer解决重叠问题 问题:如果在地图上加载成百上千工程点时,会密密麻麻,外观不是很好看,怎么破? 解决方法: ...
- ArcGIS API for Silverlight 调用WebService出现跨域访问报错的解决方法
原文:ArcGIS API for Silverlight 调用WebService出现跨域访问报错的解决方法 群里好几个朋友都提到过这样的问题,说他们在Silverlight中调用了WebServi ...
- ArcGIS API for Silverlight 调用GP服务绘制等值面
原文:ArcGIS API for Silverlight 调用GP服务绘制等值面 GP服务模型如下图: 示例效果图片如下:
- ArcGIS API for Silverlight代码中使用Template模板
原文:ArcGIS API for Silverlight代码中使用Template模板 在项目开发中,会遇到点选中聚焦闪烁效果,但是因为在使用Symbol的时候,会设置一定的OffSetX和OffS ...
- ArcGIS API for Silverlight实现地图测距功能
原文:ArcGIS API for Silverlight实现地图测距功能 问题:如何实现地图测距功能? 地图工具栏 <Grid x:Name="gToolMenu" Hei ...
随机推荐
- zw版【转发·台湾nvp系列Delphi例程】HALCON SigmaImage2
zw版[转发·台湾nvp系列Delphi例程]HALCON SigmaImage2 procedure TForm1.Button1Click(Sender: TObject);var op: HOp ...
- NOSQL学习之一:Memcached, Redis, MongoDB区别
Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理. Memcached是一个自由开源的,高性能,分布式内存对象缓存系统. MongoDB是一个基于分布 ...
- JavaScript位运算符
位运算符是在数字底层(即表示数字的 32 个数位)进行操作的. 重温整数 ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数).在 ECMAScript ...
- JProfiler8 远程监控tomcat配置过程
1. 阅读人群 1.熟悉liunx服务器,起码知道liunx常见的命令 2.熟悉tomcat容器,起码知道怎么tomcat的启动以及停止 3.熟悉java编程语言,JProfiler8是专门监控jav ...
- Linux中Postfix邮件原理介绍(一)
邮件相关协议 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议, 工作在TCP的25端口.它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式 ...
- IT行业——Linux
现在是21世纪,是科学技术大力发展的一个时代,IT行业已经成为现在的一个非常热门的一个行业,许许多多的人都想要往IT方面发展,找IT方面相关的一个工作.因此,现在也出现了很多IT培训机构,比如培训Li ...
- 20145324王嘉澜 《网络对抗》进阶实践之 shellcode注入和Return-to-libc攻击深入
Shellcode注入 •Shellcode实际是一段代码,但却作为数据发送给受攻击服务器,将代码存储到对方的堆栈中,并将堆栈的返回地址利用缓冲区溢出,覆盖成为指向 shellcode的地址 •实验参 ...
- cogs 330. [NOI2003] 文本编辑器
★★★ 输入文件:editor2003.in 输出文件:editor2003.out 简单对比 时间限制:2 s 内存限制:128 MB [问题描述] 很久很久以前,DOS3.x的程序 ...
- Python3基础 pickle.dump和load 对一个对象进行序列化存储及读取
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- BZOJ2563: 阿狸和桃子的游戏 贪心
Description 阿狸和桃子正在玩一个游戏,游戏是在一个带权图G=(V, E)上进行的,设节点权值为w(v),边权为c(e).游戏规则是这样的: 1. 阿狸和桃子轮流将图中的顶点染色,阿狸会将顶 ...