SL API 与 JS API的交互

我们知道,Siverlight 作为 浏览器的一个插件,就相当于程序的容器,那么我们怎样和Html 中的JS 代码交互呢,其实微软给我们了解决方案. 参考文章http://www.cnblogs.com/HellenTian/archive/2010/11/11/1874711.html

 

1.Silverlight 来调用Javascript 。比如我想显示两个Map  一个Map 是Silverlight API 来写,另一个Map  用 JS API来写.实现两个Map的联动效果。当我 SL中的Map的Extent的发生变化时,JS中MAP 相应也变化到相同的Extent。

我们可以在JS 文件里写一个 jssetextent 函数来来对MAP的Extent进行 设置,在SIlverlight中进行调用。首先我在我的HTMl页面如下:

[html]   view plain copy
  1. <span style="font-size:18px;"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <head>  
  4.     <title>JSANDSLAPI</title>  
  5.     <style type="text/css">  
  6.         html, body  
  7.         {  
  8.             height: 100%;  
  9.             overflow: auto;  
  10.         }  
  11.         body  
  12.         {  
  13.             padding: 0;  
  14.             margin: 0;  
  15.         }  
  16.         #silverlightControlHost  
  17.         {  
  18.             height: 100%;  
  19.             text-align: center;  
  20.         }  
  21.         #jsdiv  
  22.         {  
  23.             height: 80%;  
  24.             width: 45%;  
  25.             float: left;  
  26.             background-color: #3FC;  
  27.         }  
  28.     </style>  
  29.     <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.2/js/dojo/dijit/themes/claro/claro.css"/>  
  30.     <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.2/js/esri/css/esri.css" />  
  31.      
  32.         <script type="text/javascript" src="Silverlight.js"></script>  
  33.     <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>  
  34.     <script type="text/javascript">        var djConfig = { parseOnLoad: true };</script>  
  35.     <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=3.2"></script>  
  36.   
  37.     <script type="text/javascript">  
  38.     function onSilverlightError(sender, args) {  
  39.     var appSource = "";  
  40.     if (sender != null && sender != 0) {  
  41.         appSource = sender.getHost().Source;  
  42.     }  
  43.   
  44.     var errorType = args.ErrorType;  
  45.     var iErrorCode = args.ErrorCode;  
  46.   
  47.     if (errorType == "ImageError" || errorType == "MediaError") {  
  48.         return;  
  49.     }  
  50.   
  51.     var errMsg = "Unhandled Error in Silverlight Application " + appSource + "\n";  
  52.   
  53.     errMsg += "Code: " + iErrorCode + "    \n";  
  54.     errMsg += "Category: " + errorType + "       \n";  
  55.     errMsg += "Message: " + args.ErrorMessage + "     \n";  
  56.   
  57.     if (errorType == "ParserError") {  
  58.         errMsg += "File: " + args.xamlFile + "     \n";  
  59.         errMsg += "Line: " + args.lineNumber + "     \n";  
  60.         errMsg += "Position: " + args.charPosition + "     \n";  
  61.     }  
  62.     else if (errorType == "RuntimeError") {  
  63.         if (args.lineNumber != 0) {  
  64.             errMsg += "Line: " + args.lineNumber + "     \n";  
  65.             errMsg += "Position: " + args.charPosition + "     \n";  
  66.         }  
  67.         errMsg += "MethodName: " + args.methodName + "     \n";  
  68.     }  
  69.   
  70.     throw new Error(errMsg);  
  71. }  
  72.   
  73.     </script>  
  74.     <script type="text/javascript">  
  75.         dojo.require("dijit.layout.BorderContainer");  
  76.         dojo.require("dijit.layout.ContentPane");  
  77.         dojo.require("esri.map");  
  78.         var map; function init() {  
  79.             var initExtent = new esri.geometry.Extent({ "xmin": -27141257.7092732, "ymin": -31127629.9353227, "xmax": 27141257.7092732, "ymax": 31127629.9353228, "spatialReference": { "wkid": 102100} });  
  80.             map = new esri.Map("jsdiv", {  
  81.                 extent: esri.geometry.geographicToWebMercator(initExtent)  
  82.             });  
  83.   
  84.             var basemap = new esri.layers.ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");  
  85.             map.addLayer(basemap);  
  86.               
  87.             dojo.connect(map, 'onLoad', function (theMap) {  
  88.                   
  89.                 dojo.connect(dijit.byId('map'), 'resize', map, map.resize);  
  90.             });  
  91.          
  92.   
  93.         } dojo.addOnLoad(init);  
  94.   
  95.   
  96.         function jssetextent(xmin, xmax, ymin, ymax) {  
  97.   
  98.                     var myextent = new esri.geometry.Extent({ "xmin": parseFloat(xmin), "ymin": parseFloat(ymin), "xmax": parseFloat(xmax), "ymax": parseFloat(ymax), "spatialReference": { "wkid": 102100} });  
  99.   
  100.                     map.setExtent(myextent);  
  101.                 }  
  102.          </script>  
  103. </head>  
  104. <body>  
  105.     <div style="float: left; height: 80%; width: 50%; background-color: #036">  
  106.         <form id="form1" runat="server" style="height: 100%; width: 100%; background-color: #036">  
  107.         <div id="silverlightControlHost">  
  108.             <object id="SLContainer" data="data:application/x-silverlight-2," type="application/x-silverlight-2"  
  109.                 width="100%" height="100%">  
  110.                 <param name="source" value="ClientBin/JSANDSLAPI.xap" />  
  111.                 <param name="onError" value="onSilverlightError" />  
  112.                 <param name="background" value="white" />  
  113.                 <param name="minRuntimeVersion" value="5.0.61118.0" />  
  114.                 <param name="autoUpgrade" value="true" />  
  115.                 <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0" style="text-decoration: none">  
  116.                     <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight"  
  117.                         style="border-style: none" />  
  118.                 </a>  
  119.             </object>  
  120.             <iframe id="_sl_historyFrame" style="visibility: hidden; height: 0px; width: 0px;  
  121.                 border: 0px"></iframe>  
  122.         </div>  
  123.         </form>  
  124.     </div>  
  125.     <div id="jsdiv">  
  126.     </div>  
  127. </body>  
  128. </html>  
  129. </span>  


以上代码中<div id="silverlightControlHost"> 来作为Silverlgiht插件的容器。为 <object id="SLContainer" data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">增加一个id属性,方便JS 获取。<div id='jsdiv'> 来作为我们的JS API 的MAP的容器,并且包含了初始化MAP 并添加了一个缓存图层。红色部分 是一个定义好的函数,接受四个参数,主要功能是设置MAP的Extent ,这个函数是在后面的 Siverlight 中来调用的

在 SL中的XAML的代码如下

[html]   view plain copy
  1. <span style="font-size:18px;"><Grid x:Name="LayoutRoot" Background="White">  
  2.         <esri:Map  Background="Beige" Name="SLmap"   PanDuration="0" ExtentChanged="SLmap_ExtentChanged">  
  3.             <esri:Map.Layers>  
  4.                 <esri:LayerCollection>  
  5.                     <esri:ArcGISTiledMapServiceLayer Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer" />  
  6.                 </esri:LayerCollection>  
  7.             </esri:Map.Layers>  
  8.         </esri:Map>  
  9.     </Grid></span>  


用System.Windows.Brower命名空间下的某些silverlight类,你可以调用一段脚本写的javascript函数。这样就给你的silverlight代码一个很有规律的方式来和页面交互。

[csharp]   view plain copy
  1. <span style="font-size:18px;"></span>  
[csharp]   view plain copy
  1. <span style="font-size:18px;">  private void SLmap_ExtentChanged(object sender, ESRI.ArcGIS.Client.ExtentEventArgs e)  
  2.         {  
  3.            // string  s=SLmap.Extent  
  4.             double xmin = SLmap.Extent.XMin;  
  5.             double xmax = SLmap.Extent.XMax;  
  6.             double ymin = SLmap.Extent.YMin;  
  7.             double ymax = SLmap.Extent.YMax;  
  8.            ScriptObject scriptObjcet = (ScriptObject)HtmlPage.Window.GetProperty("jssetextent");  
  9.             scriptObjcet.InvokeSelf(xmin, xmax, ymin, ymax);  
  10.   
  11.         }</span>  

通过 HTml Page .Window .GetProperty 来 获取这个函数,剩下的就是就是传递参数然后调用了 运行的效果如下,当平移或者缩放左侧的Map时,右侧Map的范围也会发生改变

SL API 与 JS API的交互_第1张图片

 2,以上已经实现了再 SIlverlight 中调用 JS中的函数,下面开始实现一个在JS代码中来调用 SL中的函数,以实现JS与SL的互操作,我实现在 JS API中MAP中增加一个点, 然后把点的坐标传递到SL 里面来,在Sl中MAP的相同位置增加一个 点

 在javascript中调用silverlight方法,主要有以下步骤:

在silverlight程序中创建一个公开的方法来暴露你想在web页面中用的函数。

在方法上边添加一个ScriptableMember属性。

在包含这个方法的类上添加ScriptableType属性。

调用HtmlPage.RegisterScriptableObject()将这个方法暴露给javascript。

 

在 Silverlight 的XAML 文件中为MAP添加一个GraphisLayer ,并编写为此Graphicslayer添加点的代码 C#代码如下

[csharp]   view plain copy
  1.        [ScriptableType]  
  2. public partial class MainPage : UserControl  
  3. {  
  4.     public MainPage()  
  5.     {  
  6.         InitializeComponent();  
  7.         HtmlPage.RegisterScriptableObject("JSOBJ"this);  
  8.     }  
  9.   
  10.              [ScriptableMember]  
  11.     public void Addpoint(double ptx ,double pty)  
  12. {  
  13.   
  14.     MapPoint pt = new MapPoint(ptx, pty);  
  15.     SimpleMarkerSymbol makersymbol = new  SimpleMarkerSymbol();  
  16.     makersymbol.Style = SimpleMarkerSymbol.SimpleMarkerStyle.Square;  
  17.     makersymbol.Size = 10;  
  18.     Graphic g = new Graphic();  
  19.     g.Geometry = pt;  
  20.     g.Symbol = makersymbol;  
  21.     GraphicsLayer glayer = SLmap.Layers["MyGraphicslayer"as GraphicsLayer;  
  22.     glayer.Graphics.Add(g);  
  23.             
  24.             
  25. }  

为 方法所在的类以及该方法增加特性,同时将该方法所在的实例注册为JSOBJ,允许外部的JS代码可以调用 Sl内部的方法。

下面再JS文件里编写代码,在 map的点击事件里为Map 增加一个函数,增加一个graphic 同时获取AddPoint方法并调用,同时把点的坐标传递给Addpoint作为参数。

[javascript]   view plain copy
  1. dojo.connect(map, "onClick"function (evt) {  
  2.                
  3.                 var symbol1 = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE, 10, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 1), new dojo.Color([0, 255, 0, 0.25]));  
  4.                 var graphic = new esri.Graphic(evt.mapPoint, symbol1);  
  5.                 map.graphics.add(graphic);  
  6.                   
  7.               var slcontainer = document.getElementById("SLContainer");  
  8.                 slcontainer.content.JSOBJ.Addpoint(evt.mapPoint.x, evt.mapPoint.y);  
  9.   
  10.             });  


其中最后两行为获取承载Silverlight的 Object对象,然后获取刚才注册的JSOBJ,并调用Addpoint方法。运行程序,在JS MAP中鼠标点击,会发现 Silverlight中MAP中相同位置也会增加相应的点。说明我们已经完成了 在JS中调用 Silverlight的方法。结果如下;

 

 SL API 与 JS API的交互_第2张图片

以上只是简单的介绍了 使用Silverlight 与javascript的交互操作,证明了技术的可行性。为我们开发GIS应用提供了新的选择,让我们更方便的使用这些技术的,充分发挥Silverlight或者JS的优点,当然可以结合更多的空间分析。。

demo下载地址

你可能感兴趣的:(SL API 与 JS API的交互)