
点击这里,直接看效果
根据上一节的知识,可以知道这个Silverlight程序里包含了一个Map控件,并且里面至少有一个WorldImagery的图层。那么Page.xaml里的关键代码开起来应该是这样的:
<GrID x:name="LayoutRoot"><esri:Map x:name="Map1">
<esri:Map.Layers>
<esri:ArcGISTiledMapServiceLayer ID="WorldImageLayer" x:name="WorldImageLayer" Initialized="WorldImageLayer_Initialized"
Url="http://services.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/MapServer" />
</esri:Map.Layers>
</esri:Map>
</GrID> 复制代码 所有的布局工作都在一个GrID中进行,给它起个名字叫LayoutRoot。GrID里面放了一个esri:Map元素(Map控件),它继承自Silverlight的Control,所以拥有WIDth和Height属性,默认是auto,自动填充整个GrID。Map.Layers是一个集合,可以往里面添加layer,这里的layer指的是ArcGIS Server或其他软件发布的地图服务,目前SilverlightAPI中支持的能够直接使用的有ArcGISDynamicMapServiceLayer,ArcGISTiledMapServiceLayer,ArcGISImageServiceLayer,分别对应ArcGIS Server发布的动态地图服务,缓存地图服务(两种Map Service)和ImageService,这三种图层是拿来即用的,如果你想加入别的地图服务,比如WMS服务,则需要自己继承相应类型的的Layer;此外还有Graphicslayer,ElementLayer,SilverlightAPI特有的FeatureLayer等。这些都会在之后的小节中讲到。强调一下,与ADF开发里MapResourceManager一样,在Map中加入的内容实际上是地图服务,但当做一个layer处理。
下面就对这个例子中的每一部分来做说明(与上图中的序号相对应)。
1、当地图移动时获取地图范围。
当地图范围改变后,显示出当前地图范围的边界值。
这部分的页面布局是这样的: <GrID x:name="GrIDright" margin="0,15,20,0" HorizontalAlignment="Right" VerticalAlignment="Stretch">
<!--extent-->
<Canvas WIDth="215" Height="110" VerticalAlignment="top">
<Rectangle Style="{StaticResource rectBottom}" />
<Rectangle Style="{StaticResource rectMIDdle}" />
<Rectangle Style="{StaticResource recttop}" />
<TextBlock x:name="TBextent" margin="20,0" Text="范围:" textwrapPing="Wrap" FontWeight="Bold" />
</Canvas>
</GrID> 复制代码 有关xaml中详细的布局知识请大家参照其他例子学习,这里稍作讲解。外面的GrIDright这个GrID就是页面右边1、2、3、6的父容器,之所以不用StackPanel是因为6需要贴着页面底部,StackPanel中的元素都会flow贴到一起。三个矩形组合便构成了整体轮廓,由于它们都在一个Canvas中,所以会产生压盖效果。最先加入的rectBottom这个矩形便是最底下的阴影效果,中间的矩形是蓝色框,最上面的矩形是白色的文字显示区域。“{ }”里的内容在xaml中称作markupextention,StaticResource是使用在别处已经定义好的资源(resource)来对本元素的一些属性进行自动赋值,这里用来修饰Rectangle的外观。xaml中除了StaticResource这种markupextention之外还有Binding和TemplateBinding两种markup extention,分别用于数据绑定(databinding)和自定义control的外观。上面的StaticResource是在App.xaml中定义的,这样就可以在本工程的任何页面中使用,当然也可以定义为LayoutRoot这个GrID的Resource。贴出来大家一看就明白了: <Application.Resources>
<Style x:Key="rectBottom" targettype="Rectangle">
<Setter Property="RadiusX" Value="10" />
<Setter Property="RadiusY" Value="10" />
<Setter Property="Fill" Value="#22000000" />
<Setter Property="Canvas.left" Value="5" />
<Setter Property="Canvas.top" Value="5" />
<Setter Property="WIDth" Value="215" />
<Setter Property="Height" Value="110" />
</Style>
<Style x:Key="rectMIDdle" targettype="Rectangle">
<Setter Property="RadiusX" Value="10" />
<Setter Property="RadiusY" Value="10" />
<Setter Property="Fill" Value="#775C90B2" />
<Setter Property="Canvas.left" Value="0" />
<Setter Property="Canvas.top" Value="0" />
<Setter Property="WIDth" Value="215" />
<Setter Property="Height" Value="110" />
<Setter Property="stroke" Value="Gray" />
</Style>
<Style x:Key="recttop" targettype="Rectangle">
<Setter Property="RadiusX" Value="5" />
<Setter Property="RadiusY" Value="5" />
<Setter Property="Fill" Value="#FFFFFFFF" />
<Setter Property="Canvas.left" Value="10" />
<Setter Property="Canvas.top" Value="10" />
<Setter Property="WIDth" Value="195" />
<Setter Property="Height" Value="90" />
<Setter Property="stroke" Value="DarkGreen" />
</Style>
</Application.Resources> 复制代码 它们就相当于网页中的CSS。如果不使用StaticResource,那么三个矩形看起来应该是这样的: <Rectangle RadiusX="10" RadiusY="10" Fill="#22000000" Canvas.left="5" Canvas.top="5" WIDth="215" Height="110" />
<Rectangle RadiusX="10" RadiusY="10" Fill="#775C90B2" Canvas.left="0" Canvas.top="0" WIDth="215" Height="110" stroke="Gray" />
<Rectangle RadiusX="5" RadiusY="5" Fill="#FFFFFFFF" Canvas.left="10" Canvas.top="10" WIDth="195" Height="90" stroke="DarkGreen" /> 复制代码 你猜的没错,在其他矩形框部分也使用到了这些属性。通过实践可以感受到,xaml中的布局在一般使用中比HTML+CSS的布局要简单和灵活许多。好了,继续。
Map控件里面已经封装了一些事件来供我们使用,我们可以在需要的时候捕获它们来进行处理。如果做过ArcGIS产品的二次开发,你应该已经想到我们要捕获的就是Map的ExtentChanged事件;而要在地图移动或者缩放的过程中也实时显示地图范围,则还要对ExtentChanging事件做处理。细心的你可能已经发现,在上面的xaml代码中已经对世界地图这个图层的Initialized事件添加了一个hanlder:WorldImageLayer_Initialized。当然可以像这样一样给Map的这两个事件添加handler,但这里并不这么做,而是在世界地图图层的Initialized事件里来绑定它们(移动地图时出发ExtentChanged事件,网速过慢导致图层并未加入到Map中,则会报错)。来看看Page.xaml.cs中的code-behind代码: private voID WorldImageLayer_Initialized(object sender,EventArgs e)
{
Map1.ExtentChanged += new EventHandler<ESRI.ArcGIS.ExtentEventArgs>(Map1_ExtentChange);
Map1.ExtentChanging += new EventHandler<ESRI.ArcGIS.ExtentEventArgs>(Map1_ExtentChange);
} 复制代码 没错,把两个事件绑定到同一个handler即可。再看看Map1_ExtentChange中的代码: private voID Map1_ExtentChange(object sender,ESRI.ArcGIS.ExtentEventArgs e)
{
TBextent.Text = string.Format("地图范围:\nMinX:{0}\nMinY:{1}\nMaxX:{2}\nMaxY:{3}",
e.NewExtent.XMin,e.NewExtent.YMin,e.NewExtent.XMax,e.NewExtent.YMax);
} 复制代码 很简单吧?顺便提一下,ExtentEventArgs里既然有NewExtent,当然就有oldExtent了,通过比较这两个变量就可以分析出当前进行的是放大、缩小还是平移 *** 作了。其实还有个更简单的办法,查查看Map的Resolution属性吧。
对于Silverlight API中内容,是不是感觉很容易呢(当然你得做够xaml的功课才行)?那么赶快来看第二部分。
2、当鼠标移动时获取鼠标坐标。
包括屏幕坐标和地图坐标。外观样式方面是这样的: <!--mouse coords-->
<Canvas WIDth="215" Height="110" margin="0,120,0" VerticalAlignment="top">
<Rectangle Style="{StaticResource rectBottom}" />
<Rectangle Style="{StaticResource rectMIDdle}" />
<Rectangle Style="{StaticResource recttop}" />
<StackPanel OrIEntation="Vertical" margin="20,0">
<TextBlock x:name="TBscreencoords"
HorizontalAlignment="left" VerticalAlignment="Center" Text="屏幕坐标:" textwrapPing="Wrap" FontWeight="Bold" />
<TextBlock x:name="TBmapcoords"
HorizontalAlignment="left" VerticalAlignment="Center" Text="地图坐标:" textwrapPing="Wrap" FontWeight="Bold" />
</StackPanel>
</Canvas> 复制代码 那么接下来要捕捉那个事件呢?当然就是MouseMove啦。不过如果查看SilverlightAPI中的Map类,发现并没有这个事件。但要记住Map是继承自xaml中的Control,Control继承自FrameworkElement,FrameworkElement继承自UIElement,这里就有一个MouseMove事件了。所以Map控件的MouseMove是xaml中而不是Siverlight API中的事件(当然整个SilverlightAPI都是建立在xaml基础上的)。在esri:Map标签中添加一个MouseMove事件(MouseMove="Map1_MouseMove"),来看看code-behind代码: private voID Map1_MouseMove(object sender,MouseEventArgs e)
{
if (Map1.Extent != null)
{
System.windows.Point screenPnt = e.Getposition(Map1);
TBscreencoords.Text = string.Format("屏幕坐标:\nX:{0},Y:{1}",screenPnt.X,screenPnt.Y);
ESRI.ArcGIS.Geometry.MapPoint mapPnt = Map1.ScreenToMap(screenPnt);
TBmapcoords.Text = string.Format("地图坐标:\nX:{0}\nY:{1}",Math.Round(mapPnt.X,4),Math.Round(mapPnt.Y,4));
}
} 复制代码 可以看到Map控件提供了屏幕与地图坐标之间转换的方法,好比开发人员的一座桥梁,用来往返于Silverlight特性与地图之间,非常方便。需要说明的是,这里Getposition(Map1)获得的屏幕坐标是相对于Map控件的,而不是显示器的左上角。ok,继续来看第三部分。
3、Map里的动画效果。
当地图放大和平移时都可以看到平滑的效果,这归功于Silverlight的动画功能。Map在封装完动画效果后,给了我们两个属性来对它们进行设置:PanDuration和ZoomDuration,用于设置这两个动作持续的时间。它们都是TimeSpan类型的变量,合理的设置可以带来良好的用户体验。看看这部分的布局: <!--map animation slIDer-->
<Canvas WIDth="215" Height="130" margin="0,240,0" VerticalAlignment="top">
<Rectangle Style="{StaticResource rectBottom}" Height="130" />
<Rectangle Style="{StaticResource rectMIDdle}" Height="130" />
<Rectangle Style="{StaticResource recttop}" Height="110" />
<StackPanel OrIEntation="Vertical" margin="20,0">
<TextBlock HorizontalAlignment="left" Text="设置地图缩放动作持续时间:" textwrapPing="Wrap" FontWeight="Bold" />
<TextBlock x:name="TBzoomdurationvalue" HorizontalAlignment="left" Text="当前值:" textwrapPing="Wrap" FontWeight="Bold" />
<SlIDer x:name="slIDerzoomanimation" OrIEntation="Horizontal" Minimum="0" Maximum="20" SmallChange="1"
LargeChange="5" Cursor="Hand" ValueChanged="slIDeranimation_ValueChanged" WIDth="180" />
<TextBlock HorizontalAlignment="left" Text="设置地图平移动作持续时间:" textwrapPing="Wrap" FontWeight="Bold" />
<TextBlock x:name="TBpandurationvalue" HorizontalAlignment="left" Text="当前值:" textwrapPing="Wrap" FontWeight="Bold" />
<SlIDer x:name="slIDerpananimation" OrIEntation="Horizontal" Minimum="0" Maximum="20" SmallChange="1"
LargeChange="5" Cursor="Hand" ValueChanged="slIDeranimation_ValueChanged" WIDth="180" />
</StackPanel>
</Canvas> 复制代码 主要用到了两个slIDer控件。再看看拖动滑块时的事件代码,为了省事,这两个事件也用了同一个handler: private voID slIDeranimation_ValueChanged(object sender,RoutedPropertyChangedEventArgs e)
{
SlIDer s=sender as SlIDer;
if (s.name == "slIDerzoomanimation")
{
Map1.ZoomDuration = new TimeSpan(0,Convert.ToInt32(slIDerzoomanimation.Value));
TBzoomdurationvalue.Text = string.Format("当前值:{0}秒",Convert.ToInt32(slIDerzoomanimation.Value));
}
else
{
Map1.PanDuration = new TimeSpan(0,Convert.ToInt32(slIDerpananimation.Value));
TBpandurationvalue.Text = string.Format("当前值:{0}秒",Convert.ToInt32(slIDerpananimation.Value));
}
} 复制代码 对应着地图效果,应该很容易理解。继续第四部分。
4、对地图服务可见性与动态地图服务中图层可见性的控制。
还是要强调一下,WorldImagery和StreetMap两个能看到的地图实际上都是地图服务,当作layer加入到了Map控件中;而动态地图服务USA中的图层CitIEs,Rivers,States才是与ArcMap中图层相对的概念。对于WorldImagery和StreetMap之间的切换,主要用到了Silverlight API里Layer的
Visible属性;而动态服务中图层可见性的 *** 作,主要是对ArcGISDynamicMapServiceLayer的VisibleLayers数组做了设置。
StreetMap这个服务其实一开始就加入了地图(在esri:Map标签中): <esri:ArcGISTiledMapServiceLayer ID="StreetMapLayer"
Url="http://services.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer" Visible="False" /> 复制代码 而设置了Visible="False"。图层不可见时地图不会对它做任何处理,所以不用担心会耗费流量或加重程序负担。
看看布局部分: <StackPanel HorizontalAlignment="left" margin="20,0">
<Canvas x:name="Canvasleft" WIDth="165" Height="90" HorizontalAlignment="left" VerticalAlignment="top">
<Rectangle Style="{StaticResource rectBottom}" WIDth="165" Height="90" />
<Rectangle Style="{StaticResource rectMIDdle}" Fill="#7758FF00" WIDth="165" Height="90" />
<Rectangle Style="{StaticResource recttop}" WIDth="145" Height="70" />
<!--change layer-->
<StackPanel margin="20,0">
<TextBlock Text="切换图层:" textwrapPing="Wrap" FontWeight="Bold" />
<StackPanel OrIEntation="Horizontal">
<Togglebutton x:name="TBimagery" Content="Imagery" Click="TBimagery_Clicked" Cursor="Hand" />
<Togglebutton x:name="TBstreetmap" Content="StreetMap" Click="TBstreetmap_Clicked" Cursor="Hand" />
</StackPanel>
<CheckBox margin="0,5,0" x:name="chkBoxDynamicLayer" Content="添加一个动态图层吧" IsChecked="False" Click="chkBoxDynamicLayer_Click" Cursor="Hand" />
</StackPanel>
</Canvas>
</StackPanel> 复制代码 这里使用了Togglebutton,CheckBox和Radiobutton都由它派生而来。Silverlight2中的Togglebutton不能设置Group(一个Group中自动限定同时只能有一个控件处于激活状态),不如Flex里的Togglebutton来的方便,所以code-behind中多做了些工作。当然这里使用Radiobutton也是可以的。 private voID TBimagery_Clicked(object sender,RoutedEventArgs e)
{
if (TBstreetmap.IsChecked==true)
{
Map1.Layers["WorldImageLayer"].Visible = true;
Map1.Layers["WorldImageLayer"].Opacity = 0;
TBstreetmap.IsChecked = false;
Storyboard sbworldmapshow = makestoryboard("WorldImageLayer",1);
Storyboard sbstreetmaphIDe = makestoryboard("StreetMapLayer",1,0);
sbworldmapshow.Begin();
sbstreetmaphIDe.Begin();
hIDelayername = "StreetMapLayer";
timer.Begin();
}
TBimagery.IsChecked = true;
}
private voID TBstreetmap_Clicked(object sender,RoutedEventArgs e)
{
if (TBimagery.IsChecked==true)
{
Map1.Layers["StreetMapLayer"].Visible = true;
Map1.Layers["StreetMapLayer"].Opacity = 0;
TBimagery.IsChecked = false;
Storyboard sbstreetmapshow = makestoryboard("StreetMapLayer",1);
Storyboard sbworldmaphIDe = makestoryboard("WorldImageLayer",0);
sbstreetmapshow.Begin();
sbworldmaphIDe.Begin();
hIDelayername = "WorldImageLayer";
timer.Begin();
}
TBstreetmap.IsChecked = true;
}
private voID timer_Tick(object sender,EventArgs e)
{
Map1.Layers[hIDelayername].Visible = false;
}
public Storyboard makestoryboard(string layername,double from,double to)
{
Storyboard sb = new Storyboard();
ESRI.ArcGIS.ArcGISTiledMapServiceLayer layer = Map1.Layers[layername] as ESRI.ArcGIS.ArcGISTiledMapServiceLayer;
DoubleAnimation doubleAnim = new DoubleAnimation();
doubleAnim.Duration = new TimeSpan(0,5);
doubleAnim.From = from;
doubleAnim.To = to;
Storyboard.SetTarget(doubleAnim,layer);
Storyboard.SetTargetProperty(doubleAnim,new PropertyPath("Opacity"));
sb.Children.Add(doubleAnim);
return sb;
} 复制代码 当切换两个地图服务时能够看到一个渐变的效果,这里用到了Silverlight中的动画,它们都是在StoryBoard里面进行的,以后的小节中会讲Silverlight中的动画,这里不再废话了,有兴趣的朋友可以自己参考帮助学习。hIDelayername是这个一个公用的string变量,用来在切换的动画效果完成后设置不可见的图层Visible属性。timer也是一个StoryBoard: <Storyboard x:name="timer" Completed="timer_Tick" Duration="0:0:5" /> 复制代码 这里可以看出把StoryBoard也能巧妙的用作计时器。到了特定时间(5秒)后会自动timer_Tick函数,当然也可以使用.net中的各种timer类。
下面是添加动态服务的部分。 private voID chkBoxDynamicLayer_Click(object sender,RoutedEventArgs e)
{
if (chkBoxDynamicLayer.IsChecked == true)
{
Map1.Layers.Add(california);
Map1.ZoomTo(california.FullExtent);
if (california.IsInitialized == false)
{
chkBoxDynamicLayer.IsEnabled = false;
}
chkBoxDynamicLayer.Content = "去掉它";
SVlayers.Visibility = Visibility.Visible;
}
else
{
Map1.Layers.Remove(california);
chkBoxDynamicLayer.Content = "添加一个动态图层吧";
SVlayers.Visibility = Visibility.Collapsed;
}
}
private voID dynamiclayer_initialized(object s,EventArgs e)
{
//若图层没有初始化好就移除图层,当然会报错了,所以这样做就不会了
chkBoxDynamicLayer.IsEnabled = true;
Map1.ZoomTo(california.InitialExtent);
SVlayers.Visibility = Visibility.Visible;
california.ID = "layercalifornia";
ESRI.ArcGIS.ArcGISDynamicMapServiceLayer dynamicServiceLayer = s as ESRI.ArcGIS.ArcGISDynamicMapServiceLayer;
if (dynamicServiceLayer.VisibleLayers == null)
dynamicServiceLayer.VisibleLayers = GetDefaultVisibleLayers(dynamicServiceLayer);
UpdateLayerList(dynamicServiceLayer);
} 复制代码 当添加了动态服务后,会自动d出一个ListBox,当然这些也都是在xaml中定义好的(加在上面的Canvas后面): <ScrollVIEwer x:name="SVlayers" WIDth="165" Visibility="Collapsed" Height="120">
<ListBox x:name="LayerVisibilityListBox" >
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox margin="2" name="{Binding LayerIndex}" Content="{Binding Layername}"
Tag="{Binding Servicename}" IsChecked="{Binding Visible}"
ClickMode="Press" Click="chkBoxToggleVilible_Click" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollVIEwer> 复制代码 这里把ListBox放到了ScrollVIErwer中,固定了它的高度,当内容过多时可以自动显示纵向滚动条。这里要提一下,ListBox的内容用到了数据绑定(参考xaml中的DataBinding,有OneTime,OneWay和TwoWay三种模式,这里使用的是默认的OneWay),看起来里面只有一个CheckBox,但它相当于一个模板,在code-behind中设置了ListBox.ItemSource之后,根据该属性的内容自动生成多个CheckBox。代码中自定义了一个LayerListData类,它的几个属性分别与上面的CheckBox属性绑定;将一个List赋给了ListBox.ItemSource,则会自动生成ListBox中的内容。通过一个List类型变量,来控制动态服务的可见图层。代码如下: public class LayerListData
{
public bool Visible { get; set; }
public string Servicename { get; set; }
public string Layername { get; set; }
public int LayerIndex { get; set; }
}
private int[] GetDefaultVisibleLayers(ESRI.ArcGIS.ArcGISDynamicMapServiceLayer dynamicService)
{
List<int> visibleLayerIDList = new List<int>();
ESRI.ArcGIS.LayerInfo[] layerInfoArray = dynamicService.Layers;
for (int index = 0; index < layerInfoArray.Length; index++)
{
if (layerInfoArray[index].DefaultVisibility)
visibleLayerIDList.Add(index);
}
return visibleLayerIDList.ToArray();
}
private voID UpdateLayerList(ESRI.ArcGIS.ArcGISDynamicMapServiceLayer dynamicServiceLayer)
{
int[] visibleLayerIDs = dynamicServiceLayer.VisibleLayers;
if (visibleLayerIDs == null)
visibleLayerIDs = GetDefaultVisibleLayers(dynamicServiceLayer);
List<LayerListData> visibleLayerList = new List<LayerListData>();
ESRI.ArcGIS.LayerInfo[] layerInfoArray = dynamicServiceLayer.Layers;
for (int index = 0; index < layerInfoArray.Length; index++)
{
visibleLayerList.Add(new LayerListData()
{
Visible = visibleLayerIDs.Contains(index),
Servicename = dynamicServiceLayer.ID,
Layername = layerInfoArray[index].name,
LayerIndex = index
});
}
LayerVisibilityListBox.ItemsSource = visibleLayerList;
}
voID chkBoxToggleVilible_Click(object sender,RoutedEventArgs e)
{
CheckBox tickedCheckBox = sender as CheckBox;
string servicename = tickedCheckBox.Tag.ToString();
bool visible = (bool)tickedCheckBox.IsChecked;
int layerIndex = Int32.Parse(tickedCheckBox.name);
ESRI.ArcGIS.ArcGISDynamicMapServiceLayer dynamicServiceLayer = Map1.Layers[servicename] as
ESRI.ArcGIS.ArcGISDynamicMapServiceLayer;
List<int> visibleLayerList =
dynamicServiceLayer.VisibleLayers != null
? dynamicServiceLayer.VisibleLayers.ToList() : new List<int>();
if (visible)
{
if (!visibleLayerList.Contains(layerIndex))
visibleLayerList.Add(layerIndex);
}
else
{
if (visibleLayerList.Contains(layerIndex))
visibleLayerList.Remove(layerIndex);
}
dynamicServiceLayer.VisibleLayers = visibleLayerList.ToArray();
} 复制代码 5、比例尺。
Silverlight API提供了一个Scalebar类,可以方便的设置地图比例尺。 <!--scale bar 放在LayoutRoot GrID中-->
<Canvas HorizontalAlignment="left" VerticalAlignment="Bottom" margin="10,20">
<esri:Scalebar x:name="scalebar" MapUnit="Decimaldegrees" displayUnit="Kilometers" Foreground="Black" Fillcolor1="White" Fillcolor2="Blue" />
</Canvas> 复制代码 需要在初始化的时候设置scalebar的Map属性,顺便来看看整个页面的初始化工作: namespace demo_02_extendedmap
{
public partial class Page : UserControl
{
private ESRI.ArcGIS.ArcGISDynamicMapServiceLayer california = new ESRI.ArcGIS.ArcGISDynamicMapServiceLayer();
private string hIDelayername;
public Page()
{
InitializeComponent();
scalebar.Map = Map1;
scalebarstoryboard.Begin();
TBzoomdurationvalue.Text = string.Format("当前值:{0}.{1}秒",Map1.ZoomDuration.Seconds,Map1.ZoomDuration.Milliseconds);
TBpandurationvalue.Text = string.Format("当前值:{0}.{1}秒",Map1.PanDuration.Seconds,Map1.PanDuration.Milliseconds);
california.Url = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitIEsRivers_USA/MapServer";
california.Opacity = 0.5;
california.Initialized += new EventHandler<EventArgs>(dynamiclayer_initialized);
TBimagery.IsChecked = true;
makestoryboard("WorldImageLayer",1).Begin();
//切换全屏/窗口
Application.Current.Host.Content.FullScreenChanged += new EventHandler(fullscreen_changed);
}
}
} 复制代码 scalebarstoryboard是xaml里自定义的一个动画,效果见比例尺旁的单位。
6、地图相关 *** 作。
Map控件已经内置了一些键盘鼠标事件,但目前不能像JavaScriptAPI中那样禁用这些事件。这里还用到了Silverlight程序的一个全屏特性,其实是对Application.Current.Host.Content的一个属性做了设置。直接看代码吧: <!--operation info-->
<Canvas WIDth="215" Height="110" margin="0,30" VerticalAlignment="Bottom">
<Rectangle Style="{StaticResource rectBottom}" />
<Rectangle Style="{StaticResource rectMIDdle}" Fill="#77FF0000" />
<Rectangle Style="{StaticResource recttop}" />
<TextBlock margin="20,0" textwrapPing="Wrap"
Text="地图 *** 作提示:双击放大 Shift+拖拽:放大到指定范围 Ctrl+Shift+拖拽:缩小到指定范围" />
<Togglebutton x:name="TBfullscreen" Content="点击切换地图全屏" HorizontalAlignment="Center" Canvas.left="100" Canvas.top="15" Height="30" Click="TBfullscreen_Click" />
</Canvas> 复制代码 放到GrIDright GrID中, private voID TBfullscreen_Click(object sender,RoutedEventArgs e)
{
System.windows.Interop.Content content = Application.Current.Host.Content;
content.IsFullScreen=!content.IsFullScreen;
}
private voID fullscreen_changed(object o,EventArgs e)
{
System.windows.Interop.Content content=Application.Current.Host.Content;
TBfullscreen.IsChecked = content.IsFullScreen;
} 复制代码 7、进度条。
最后还剩下地图中的这个进度条。利用了Map控件内置的一个Progress事件。 <!--progressbar 放在LayoutRoot中-->
<GrID HorizontalAlignment="Center" x:name="progressGrID" VerticalAlignment="Center" WIDth="200" Height="20" margin="5,5">
<Progressbar x:name="MyProgressbar" Minimum="0" Maximum="100" />
<TextBlock x:name="ProgressValueTextBlock" Text="100%" HorizontalAlignment="Center" VerticalAlignment="Center" />
</GrID> 复制代码 在esri:Map标签中加入一个事件:Progress="Map1_Progress", private voID Map1_Progress(object sender,ESRI.ArcGIS.ProgressEventArgs e)
{
if (e.Progress < 100)
{
progressGrID.Visibility = Visibility.Visible;
MyProgressbar.Value = e.Progress;
ProgressValueTextBlock.Text = String.Format("正在处理 {0}%",e.Progress);
}
else
{
progressGrID.Visibility = Visibility.Collapsed;
}
} 复制代码 好了到此就已经讲完了整个地图功能。尽管想尽可能详细说明每段代码,便于初学的朋友学习,但也不可能面面俱到。没有讲明白的地方大家可以自己思考,查帮助。学习的过程中,不思考,无进步。 @H_296_1404@ 总结
以上是内存溢出为你收集整理的ArcGIS API for Silverlight开发入门(2):一个基础地图实例全部内容,希望文章能够帮你解决ArcGIS API for Silverlight开发入门(2):一个基础地图实例所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)