使用js操作silverlight中的方法并获取返回的结果,这种方式网上比较多的,但通过操作silverlight的时候,调用js方法,这种方式操作的介绍就比较少了,下面我结合自己在实际开发gis业务中,框选了地图中的某个区域,将这个区域的信息反馈到html端,再使用脚本进行操作的例子介绍一下(进行操作是alert,同理,只要html端得到了silverlight的操作句柄和返回结果就可以进行任意的操作了)
大部分思想是参考了:
1、定义一个事件类MapDrawRectangleEvent,该类及其成员要可脚本化访问即加上[ScriptableType]和[ScriptableMember]注解,如下:
[ScriptableType] public class MapDrawRectangleEvent { [ScriptableMember] public void FireMapEventsAvailable() //定义了一个激发MapEventsAvailable事件的方法FireMapEventsAvailable { if (MapDrawRectangleComplete != null) { try { MapDrawRectangleComplete(this, new EventArgs()); //激发事件MapEventsAvailable,传入的参数有sender和MapEventArgs } catch (Exception ex) { throw(ex); } } } [ScriptableMember] public event EventHandler<EventArgs> MapDrawRectangleComplete; //定义了一个EventHandler类型的事件StudentsAvailable }
2、将该类在MainPage.xaml.cs文件中进行注册
MapDrawRectangleEvent mapEventObject = new MapDrawRectangleEvent(); void MainPage_Loaded(object sender, RoutedEventArgs e) void MainPage_Loaded(object sender, RoutedEventArgs e) { HtmlPage.RegisterScriptableObject("SLAPP_MapEventObject", mapEventObject); this.Drawing(); }
3、实现在silverlight地图中框选的方法即this.Drawing()中的代码,本例的silverlight使用的是ESRI的silverlight地图,实现的功能是用鼠标在地图上画一个矩形,当矩形画完时,该矩形范围内的信息被读取出来,赋值到Message属性中,并xx了上一步定义的事件:
private void Drawing() { ESRI.ArcGIS.Client.Draw draw = new ESRI.ArcGIS.Client.Draw(this.m_MapControl) { DrawMode = ESRI.ArcGIS.Client.DrawMode.Rectangle, FillSymbol = new ESRI.ArcGIS.Client.Symbols.FillSymbol() { BorderBrush = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Red), BorderThickness = 1, Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(60, 0, 0, 255)) }, LineSymbol = new ESRI.ArcGIS.Client.Symbols.LineSymbol() { Color = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Colors.Yellow), Width = 2 }, IsEnabled = true }; draw.DrawBegin += new System.EventHandler(draw_DrawBegin); draw.DrawComplete += new System.EventHandler<ESRI.ArcGIS.Client.DrawEventArgs>(draw_DrawComplete); } void draw_DrawComplete(object sender, ESRI.ArcGIS.Client.DrawEventArgs e) { ESRI.ArcGIS.Client.Tasks.QueryTask queryTaskGeometry = new ESRI.ArcGIS.Client.Tasks.QueryTask("http://192.168.0.205/ArcGIS/rest/services/unit/MapServer/0"); ESRI.ArcGIS.Client.Tasks.Query query = new ESRI.ArcGIS.Client.Tasks.Query(); query.OutFields.AddRange(new string[] { "ZQNAME" }); query.ReturnGeometry = true; query.Geometry = e.Geometry; query.Text = " "; query.Where = " 1=1 "; queryTaskGeometry.ExecuteAsync(query); queryTaskGeometry.ExecuteCompleted += new System.EventHandler<ESRI.ArcGIS.Client.Tasks.QueryEventArgs>(queryTaskGeometry_ExecuteCompleted); queryTaskGeometry.Failed += new System.EventHandler<ESRI.ArcGIS.Client.Tasks.TaskFailedEventArgs>(queryTaskGeometry_Failed); } void queryTaskGeometry_Failed(object sender, ESRI.ArcGIS.Client.Tasks.TaskFailedEventArgs e) { MessageBox.Show(e.Error.StackTrace); } void queryTaskGeometry_ExecuteCompleted(object sender, ESRI.ArcGIS.Client.Tasks.QueryEventArgs e) { string message = string.Empty; if (e.FeatureSet != null) { if (e.FeatureSet.Features.Count > 0) { foreach (var feature in e.FeatureSet.Features) { string name = feature.Attributes["ZQNAME"].ToString(); message = string.Format("{0}__{1}", message, name); } } } this.Message = message; //xx事件 mapEventObject.FireMapEventsAvailable(); } /// <summary> /// 将执行的结果信息可脚本化,js端可以获取到 /// </summary> [ScriptableMember] public string Message { get; set; }
4、在html端,编写js脚本函数,并将函数名称作为句柄赋给第1步定义的事件,该事件一定要在silverlight的onLoad事件执行之后,页面得到了silverlight对象之后进行绑定,否则silverlight对象因为要加载地图数据,还没显示出来,绑定事件的代码先执行就挂了,代码如下:
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="{bfb}" height="{bfb}"> <param name="source" value="ClientBin/FXGIS.WebGIS.xap" /> <param name="onerror" value="onSilverlightError" /> <param name="background" value="white" /> <param name="minRuntimeVersion" value="3.0.40624.0" /> <param name="autoUpgrade" value="true" /> <param name="onLoad" value="pluginLoaded" /> <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40624.0" style="text-decoration: none;"> <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="获取 Microsoft Silverlight" style="border-style: none" /> </a> </object>
注意onLoad这段要自己加上
var slControl = null; function pluginLoaded(sender, args) { // 获取Silverlight控件 slControl = sender.getHost(); slControl.Content.SLAPP_MapEventObject.MapDrawRectangleComplete = OnMapDrawRectangleComplete; } function OnMapDrawRectangleComplete(sender, args) { alert("事件被触发!"); alert(slControl.Content.SLAPP_MainPage.Message); }
至此,在silverlight地图上框选后,就能执行脚本的事件了。