ArcGIS API for Silverlight開發入門(3):Widgets

來源:互聯網
上載者:User
Widgets翻譯過來是小玩具。如果使用過Dojo或者ExtJS等js架構肯定會瞭解到這個“小玩具”也有大用處,能夠在很大程度上減少我們的工作量,快速完成功能需求。能減少多大工作量呢?讓我們先來,點擊這裡,看一個例子。

下載 (339.67 KB)2009-4-15 23:09

 

        前兩節的地圖中,總感覺少點什麼……對,就是一個sliderbar,有了它感覺就像汽車有了方向盤一樣,能夠控制方向了。那麼來看看實現上面這個例子中的滑塊條需要做什麼工作吧。
在silverlight中建立一個UserControl,把上面sliderbar的外觀和功能都封裝在裡面。
來看具體工作。vs中,在silverlight工程上按右鍵,add,new item,選擇silverlight user control,起名叫mapslider,在mapslider.xaml中填如下代碼:

  1. <Grid x:Name="slidergrid" HorizontalAlignment="Left" VerticalAlignment="Center" Background="Azure" Margin="20">
  2.         <StackPanel Orientation="Vertical">
  3.             <Button x:Name="btnzoomin" Content="+" Click="btnzoomin_Click" />
  4.             <Slider x:Name="sliderLOD" Orientation="Vertical"  Height="200" SmallChange="1" LargeChange="1"  Minimum="0" Cursor="Hand" ValueChanged="slider1_ValueChanged" />
  5.             <Button x:Name="btnzoomout" Content="-" Click="btnzoomout_Click" />
  6.         </StackPanel>
  7.     </Grid>

複製代碼

上面這些就是滑塊條的外觀,接下來看功能部分。大致思路是在mapslider類中設定一個公用屬性Map,就是需要操作的地圖了,但這個屬性不是ESRI.ArcGIS.Map,而是另一個自訂類。為什麼要這麼做?因為這個自訂類需要實現INotifyPropertyChanged介面,當我們把自己的Map控制項作為mapslider的屬性賦值的時候,這個Map需要做另外一些工作。看代碼吧,不太明白的話就要加強對silverlight中data binding的學習。在mapslider.xaml.cs頁面中填入一下代碼:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Documents;
  8. using System.Windows.Input;
  9. using System.Windows.Media;
  10. using System.Windows.Media.Animation;
  11. using System.Windows.Shapes;
  12. using System.ComponentModel;
  13. namespace customcontrol
  14. {
  15.     public partial class mapslider : UserControl
  16.     {
  17.         private mymap map = new mymap();
  18.         public ESRI.ArcGIS.Map Map
  19.         {
  20.             get
  21.             {
  22.                 return map.Map;
  23.             }
  24.             set
  25.             {
  26.                 map.Map=value;
  27.                 if (map.Map != null)
  28.                 {
  29.                     Map.ExtentChanged += new EventHandler<ESRI.ArcGIS.ExtentEventArgs>(map_ExtentChanged);
  30.                     Map.SnapToLevels = true;
  31.                     ((ESRI.ArcGIS.ArcGISTiledMapServiceLayer)Map.Layers[0]).Initialized += new EventHandler<EventArgs>(layer0_initialized);
  32.                 }
  33.             }
  34.         }
  35.         private void layer0_initialized(object o,EventArgs e)
  36.         {
  37.             sliderLOD.Maximum = ((ESRI.ArcGIS.ArcGISTiledMapServiceLayer)Map.Layers[0]).TileInfo.Lods.Length - 1;
  38.         }
  39.         public mapslider()
  40.         {
  41.             InitializeComponent();
  42.         }
  43.         private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
  44.         {
  45.             if (map.Map!=null)
  46.             {
  47.                 Map.ZoomToResolution(((ESRI.ArcGIS.ArcGISTiledMapServiceLayer)Map.Layers[0]).TileInfo.Lods[Convert.ToInt32(e.NewValue)].Resolution);
  48.             }
  49.         }
  50.         private void map_ExtentChanged(object o, ESRI.ArcGIS.ExtentEventArgs e)
  51.         {
  52.             ESRI.ArcGIS.ArcGISTiledMapServiceLayer layer = Map.Layers[0] as ESRI.ArcGIS.ArcGISTiledMapServiceLayer;
  53.             int i;
  54.             for (i = 0; i < layer.TileInfo.Lods.Length; i++)
  55.             {
  56.                 if (Map.Resolution == layer.TileInfo.Lods[i].Resolution)
  57.                     break;
  58.             }
  59.             sliderLOD.Value = i;
  60.         }
  61.         private void btnzoomin_Click(object sender, RoutedEventArgs e)
  62.         {
  63.             sliderLOD.Value += 1;
  64.         }
  65.         private void btnzoomout_Click(object sender, RoutedEventArgs e)
  66.         {
  67.             sliderLOD.Value -= 1;
  68.         }
  69.     }
  70.     //執行了這個介面後,當在首頁面page.xaml.cs中給Map賦值的時候,就能返到set語句中,以便執行綁定事件的代碼
  71.     public class mymap:INotifyPropertyChanged
  72.     {
  73.         private ESRI.ArcGIS.Map map;
  74.         public ESRI.ArcGIS.Map Map
  75.         {
  76.             get{return map;}
  77.             set
  78.             {
  79.                 map = value;
  80.                 if (PropertyChanged!=null)
  81.                 {
  82.                     PropertyChanged(this, new PropertyChangedEventArgs("Map"));
  83.                 }
  84.             }
  85.         }
  86.         public event PropertyChangedEventHandler PropertyChanged;
  87.     }
  88. }

複製代碼

做完封裝的工作,來看如何在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等類。還是通過一個例子,來看看這幾個控制項都長什麼樣吧(點擊這裡):

下載 (393.61 KB)2009-4-15 23:09

 

        MapTip需要使用到Query Task,以後的小節中再涉及到。現在分別熟悉一下這幾個Widgets的用法。
1、ToolBar和Magnifier:
        這個和ADF開發中的ToolBar(工具條)是一樣的,裡面可以添加ToolItem(工具),已實現各種功能,比如平移,縮放等。silverlight中當然要有一些比較好看的效果了,比如把滑鼠放在工具條上選擇工具的時候,會有放大效果,這個效果是預設的,不能設定;點擊一個工具時,該工具會跳動一下,這個是ToolbarItemClickEffect中的Bounce效果(目前只有Bounce和None兩個選擇),也是預設的。此例中ToolBar裡面有三個ToolBarItem,分別是Pan,FullExtent和Magnifier(本身也是一個Widget),下面是ToolBar的布局:

  1. <Grid Height="110" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,10,10,0" >
  2.             <Rectangle Fill="#22000000" RadiusX="10" RadiusY="10" Margin="0,4,0,0" />
  3.             <Rectangle Fill="#775C90B2" Stroke="Gray"  RadiusX="10" RadiusY="10" Margin="0,0,0,5" />
  4.             <Rectangle Fill="#66FFFFFF" Stroke="DarkGray" RadiusX="5" RadiusY="5" Margin="10,10,10,15" />
  5.             <StackPanel Orientation="Vertical">
  6.                 <esriWidgets:Toolbar x:Name="MyToolbar" MaxItemHeight="80" MaxItemWidth="80"
  7.                     VerticalAlignment="Top" HorizontalAlignment="Center"
  8.                     ToolbarItemClicked="MyToolbar_ToolbarItemClicked"
  9.                     ToolbarItemClickEffect="Bounce"
  10.                     Width="250" Height="80">
  11.                     <esriWidgets:Toolbar.Items>
  12.                         <esriWidgets:ToolbarItemCollection>
  13.                             <esriWidgets:ToolbarItem Text="Pan">
  14.                                 <esriWidgets:ToolbarItem.Content>
  15.                                     <Image Source="img/i_pan.png" Stretch="UniformToFill" Margin="5" />
  16.                                 </esriWidgets:ToolbarItem.Content>
  17.                             </esriWidgets:ToolbarItem>
  18.                             <esriWidgets:ToolbarItem Text="Full Screen">
  19.                                 <esriWidgets:ToolbarItem.Content>
  20.                                     <Image Source="img/i_globe.png" Stretch="UniformToFill" Margin="5" />
  21.                                 </esriWidgets:ToolbarItem.Content>
  22.                             </esriWidgets:ToolbarItem>
  23.                             <esriWidgets:ToolbarItem Text="Full Screen">
  24.                                 <esriWidgets:ToolbarItem.Content>
  25.                                     <Image Source="img/magglass.png" Stretch="UniformToFill" Margin="5"
  26.                                            MouseLeftButtonDown="Image_MouseLeftButtonDown"/>
  27.                                 </esriWidgets:ToolbarItem.Content>
  28.                             </esriWidgets:ToolbarItem>
  29.                         </esriWidgets:ToolbarItemCollection>
  30.                     </esriWidgets:Toolbar.Items>
  31.                 </esriWidgets:Toolbar>
  32.                 <TextBlock x:Name="StatusTextBlock" Text="" FontWeight="Bold" HorizontalAlignment="Center"/>
  33.             </StackPanel>
  34.         </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可以簡化我們的工作,拿來即用。但明顯的缺陷就是不靈活,如果想使自己的控制項不那麼千篇一律的話,就需要自己進行開發工作了。
原文地址:http://bbs.esrichina-bj.cn/ESRI/thread-44555-1-1.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.