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页面如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>JSANDSLAPI</title>
    <style type="text/css">
        html, body
        {
            height: 100%;
            overflow: auto;
        }
        body
        {
            padding: 0;
            margin: 0;
        }
        #silverlightControlHost
        {
            height: 100%;
            text-align: center;
        }
        #jsdiv
        {
            height: 80%;
            width: 45%;
            float: left;
            background-color: #3FC;
        }
    </style>
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.2/js/dojo/dijit/themes/claro/claro.css"/>
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.2/js/esri/css/esri.css" />
   
        <script type="text/javascript" src="Silverlight.js"></script>
    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script type="text/javascript">        var djConfig = { parseOnLoad: true };</script>
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=3.2"></script>

    <script type="text/javascript">
    function onSilverlightError(sender, args) {
    var appSource = "";
    if (sender != null && sender != 0) {
        appSource = sender.getHost().Source;
    }

    var errorType = args.ErrorType;
    var iErrorCode = args.ErrorCode;

    if (errorType == "ImageError" || errorType == "MediaError") {
        return;
    }

    var errMsg = "Unhandled Error in Silverlight Application " + appSource + "\n";

    errMsg += "Code: " + iErrorCode + "    \n";
    errMsg += "Category: " + errorType + "       \n";
    errMsg += "Message: " + args.ErrorMessage + "     \n";

    if (errorType == "ParserError") {
        errMsg += "File: " + args.xamlFile + "     \n";
        errMsg += "Line: " + args.lineNumber + "     \n";
        errMsg += "Position: " + args.charPosition + "     \n";
    }
    else if (errorType == "RuntimeError") {
        if (args.lineNumber != 0) {
            errMsg += "Line: " + args.lineNumber + "     \n";
            errMsg += "Position: " + args.charPosition + "     \n";
        }
        errMsg += "MethodName: " + args.methodName + "     \n";
    }

    throw new Error(errMsg);
}

    </script>
    <script type="text/javascript">
        dojo.require("dijit.layout.BorderContainer");
        dojo.require("dijit.layout.ContentPane");
        dojo.require("esri.map");
        var map; function init() {
            var initExtent = new esri.geometry.Extent({ "xmin": -27141257.7092732, "ymin": -31127629.9353227, "xmax": 27141257.7092732, "ymax": 31127629.9353228, "spatialReference": { "wkid": 102100} });
            map = new esri.Map("jsdiv", {
                extent: esri.geometry.geographicToWebMercator(initExtent)
            });

            var basemap = new esri.layers.ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
            map.addLayer(basemap);
            
            dojo.connect(map, 'onLoad', function (theMap) {
                
                dojo.connect(dijit.byId('map'), 'resize', map, map.resize);
            });
       

        } dojo.addOnLoad(init);


        function jssetextent(xmin, xmax, ymin, ymax) {

                    var myextent = new esri.geometry.Extent({ "xmin": parseFloat(xmin), "ymin": parseFloat(ymin), "xmax": parseFloat(xmax), "ymax": parseFloat(ymax), "spatialReference": { "wkid": 102100} });

                    map.setExtent(myextent);
                }
         </script>
</head>
<body>
    <div style="float: left; height: 80%; width: 50%; background-color: #036">
        <form id="form1" runat="server" style="height: 100%; width: 100%; background-color: #036">
        <div id="silverlightControlHost">
            <object id="SLContainer" data="data:application/x-silverlight-2," type="application/x-silverlight-2"
                width="100%" height="100%">
                <param name="source" value="ClientBin/JSANDSLAPI.xap" />
                <param name="onError" value="onSilverlightError" />
                <param name="background" value="white" />
                <param name="minRuntimeVersion" value="5.0.61118.0" />
                <param name="autoUpgrade" value="true" />
                <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0" style="text-decoration: none">
                    <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight"
                        style="border-style: none" />
                </a>
            </object>
            <iframe id="_sl_historyFrame" style="visibility: hidden; height: 0px; width: 0px;
                border: 0px"></iframe>
        </div>
        </form>
    </div>
    <div id="jsdiv">
    </div>
</body>
</html>


以上代码中<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的代码如下

<Grid x:Name="LayoutRoot" Background="White">
        <esri:Map  Background="Beige" Name="SLmap"   PanDuration="0" ExtentChanged="SLmap_ExtentChanged">
            <esri:Map.Layers>
                <esri:LayerCollection>
                    <esri:ArcGISTiledMapServiceLayer Url="http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer" />
                </esri:LayerCollection>
            </esri:Map.Layers>
        </esri:Map>
    </Grid>


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

  private void SLmap_ExtentChanged(object sender, ESRI.ArcGIS.Client.ExtentEventArgs e)
        {
           // string  s=SLmap.Extent
            double xmin = SLmap.Extent.XMin;
            double xmax = SLmap.Extent.XMax;
            double ymin = SLmap.Extent.YMin;
            double ymax = SLmap.Extent.YMax;
           ScriptObject scriptObjcet = (ScriptObject)HtmlPage.Window.GetProperty("jssetextent");
            scriptObjcet.InvokeSelf(xmin, xmax, ymin, ymax);

        }

通过 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#代码如下

           [ScriptableType]
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            HtmlPage.RegisterScriptableObject("JSOBJ", this);
        }

                 [ScriptableMember]
        public void Addpoint(double ptx ,double pty)
    {

        MapPoint pt = new MapPoint(ptx, pty);
        SimpleMarkerSymbol makersymbol = new  SimpleMarkerSymbol();
        makersymbol.Style = SimpleMarkerSymbol.SimpleMarkerStyle.Square;
        makersymbol.Size = 10;
        Graphic g = new Graphic();
        g.Geometry = pt;
        g.Symbol = makersymbol;
        GraphicsLayer glayer = SLmap.Layers["MyGraphicslayer"] as GraphicsLayer;
        glayer.Graphics.Add(g);
              
              
    }

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

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

dojo.connect(map, "onClick", function (evt) {
             
                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]));
                var graphic = new esri.Graphic(evt.mapPoint, symbol1);
                map.graphics.add(graphic);
                
              var slcontainer = document.getElementById("SLContainer");
                slcontainer.content.JSOBJ.Addpoint(evt.mapPoint.x, evt.mapPoint.y);

            });


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

 

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

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

demo下载地址

 

你可能感兴趣的:(JavaScript,function,api,Microsoft,silverlight,stylesheet)