ArcGIS API for Silverlight开发入门(3):Widgets

ArcGIS API for Silverlight开发入门(3):Widgets,第1张

概述Widgets翻译过来是小玩具。如果使用过Dojo或者ExtJS等js框架肯定会了解到这个“小玩具”也有大用处,能够在很大程度上减少我们的工作量,快速完成功能需求。能减少多大工作量呢?让我们先来,点击这里,看一个例子。 前两节的地图中,总感觉少点什么……对,就是一个sliderbar,有了它感觉就像汽车有了方向盘一样,能够控制方向了。那么来看看实现上面这个例子中的滑块条需要做什么工作吧。 在sil

Widgets翻译过来是小玩具。如果使用过Dojo或者ExtJs等Js框架肯定会了解到这个“小玩具”也有大用处,能够在很大程度上减少我们的工作量,快速完成功能需求。能减少多大工作量呢?让我们先来,点击这里,看一个例子。

前两节的地图中,总感觉少点什么……对,就是一个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,0″ >             <Rectangle Fill=”#22000000″ RadiusX=”10″ RadiusY=”10″ margin=”0,4,0″ />             <Rectangle Fill=”#775C90B2″ stroke=”Gray”  RadiusX=”10″ RadiusY=”10″ margin=”0,5″ />             <Rectangle Fill=”#66FFFFFF” stroke=”DarkGray” RadiusX=”5″ RadiusY=”5″ margin=”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可以简化我们的工作,拿来即用。但明显的缺陷就是不灵活,如果想使自己的控件不那么千篇一律的话,就需要自己进行开发工作了。
        好了,下一节中来学习一个比较重要的概念:Graphicslayer。

        前两节的地图中,总感觉少点什么……对,就是一个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,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,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可以简化我们的工作,拿来即用。但明显的缺陷就是不灵活,如果想使自己的控件不那么千篇一律的话,就需要自己进行开发工作了。        好了,下一节中来学习一个比较重要的概念:Graphicslayer。

总结

以上是内存溢出为你收集整理的ArcGIS API for Silverlight开发入门(3):Widgets全部内容,希望文章能够帮你解决ArcGIS API for Silverlight开发入门(3):Widgets所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1036731.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存