使用js操作silverlight中的方法并获取返回的结果,这种方式网上比较多的,但通过操作silverlight的时候,调用js方法,这种方式操作的介绍就比较少了,下面我结合自己在实际开发gis业务中,框选了地图中的某个区域,将这个区域的信息反馈到html端,再使用脚本进行操作的例子介绍一下(进行操作是alert,同理,只要html端得到了silverlight的操作句柄和返回结果就可以进行任意的操作了)
大部分思想是参考了:SilverLight学习笔记–Silverligh之在Javascript中捕获和处理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属性中,并激活了上一步定义的事件:
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;
//激活事件
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="100%" height="100%"> <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地图上框选后,就能执行脚本的事件了。