【Silverlight】Bing Maps開發應用與技巧三:Bing Maps Silverlight Control的離線開發

  我相信大多數使用Bing Maps開發的朋友都見過如下的畫面,就是當我們在開發Bing Maps的時候,將開發KEY填寫錯誤導致用戶授權驗證失敗出現的下圖提示錯誤。  

        

  使用Bing Maps Silverlight Control開發的缺點就在於它默認是使用的微軟自己提供的在線地圖數據,而且Bing Maps Silverlight Control還與開發者賬號進行綁定才能正常使用,如果開發KEY填寫錯誤或是不填寫開發KEY就會出現上圖的提示。實際上這個驗證失敗的提示信息是可以被屏蔽的,我們同樣是可以使用Bing Maps Silverlight Control來做我們的離線(不使用微軟的地圖數據,不通過用戶開發KEY驗證)開發的。

  通過仔細分析可知道,我們無論是做有限還是離線,本質上沒有多大的區別,不同就是所加載的地圖數據不同而已,要解決加載不同的地圖數據完全可以通過自定義TileSource實現。另外還要解決一個問題,就是在沒有通過開發KEY驗證的情況下如何把錯誤提示圖層給幹掉,也就是刪除或屏蔽錯誤提示圖層。

  實際開發中我們卻無法直接將錯誤提示層給屏蔽掉,只有通過其他間接的方式來處理。仔細查閱API可以發現,Bing Maps Silverlight Control的Map控件具有一個LoadError的事件,我們可以在此事件中動一些手腳,來把可惡的錯誤提示層給幹掉。通過Reflector反編譯可以發現LoadError事件的處理代碼:

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> private void Map_LoadingError( object sender,LoadingErrorEventArgse)
{
if ( this .loadingErrorMessage == null )
{
this .loadingErrorMessage = new LoadingErrorMessage();
base .RootLayer.get_Children().Add( this .loadingErrorMessage);
}
if (e.get_LoadingException() is UriSchemeNotSupportedException)
{
this .loadingErrorMessage.SetUriSchemeError( base .Culture);
}
else if (e.get_LoadingException() is ConfigurationNotLoadedException)
{
this .loadingErrorMessage.SetConfigurationError( base .Culture);
}
else if (e.get_LoadingException() is CredentialsInvalidException)
{
this .loadingErrorMessage.SetCredentialsError( base .Culture);
}
}

  通過反編譯和調試跟蹤可以發現Map控件的根佈局容器名爲RootLayer,其下的有多個子節點元素,其他一個就是錯誤提示層節點元素,要實現屏蔽錯誤提示信息之需要通過代碼實現將該子元素從Map控件的子元素節點中移出即可。這裏我們可以故意不填寫開發KEY並同時添加LoadError事件處理來進行測試,可得到如下圖所示的結果。

      

  可以發現當發生了錯誤引發LoadError後,就會觸發上面反編譯出來的事件委託方法,跟蹤RootLayer的子節點可以發現Map控件下共有6個子節點,且LoadErrorMessage是最後添加到Map子節點元素中的,也就是說LoadErrorMessage節點在Map控件的Children中的索引爲5,找到了具體的子節點元素現在只需要將其他隱藏或直接移除就解決了問題。

  最簡單的方式就是自己擴展一個Map控件,在其構造方法中將錯誤提示層給幹掉,然後再項目中使用自定義的Map控件,大致可以如下實現。

<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--> public class OfflineMap:Map
{
public OfflineMap()
:
base ()
{
base .LoadingError += (sender,e) =>
{
base .RootLayer.Children.RemoveAt( 5 );
};
}
}

<!--使用自定義的Map控件->
< controls:OfflineMap ></ controls:OfflineMap >

        

  最大的問題已經解決,接下來就可以根據自己的需求做離線的開發了。比如使用自己的地圖數據,詳細請查閱《Bing Maps進階系列九:使用MapCruncher進行地圖切片並集成進Bing Maps》中介紹的方法實現。或者通過自定義TileSource加載自己部署的Google本地部署的地圖數據,詳細請查閱《【Silverlight】Bing Maps學習系列(八):使用Bing Maps Silverlight Control加載自己部署的Google Maps》。

        

  PS:本文中所介紹的間接實現屏蔽錯誤提示層的方法只是暫時的可行方案,不代表以後同樣還可以通過這樣的方式去實現。在以後發佈的新版Bing Maps Silverlight Control中或許不能再使用此方法實現,請各位看友特別注意。基於本篇的實現方式,完全可以用於離線開發和離線演示使用。