Silverlight与JavaScript的交互操作
Silverlight和JavaScript交互介绍以及简单Demo演示,主要包括JavaScript操作Silverlight数据、Silverlight操作JavaScript数据以及数据模版绑定数据。
1.Silverlight和JavaScript概念
可能有的朋友对于这两技术都很熟悉,有的可能不是很熟悉,为了下面好理解简单介绍一下。
(1).JavaScript
JavaScript是一种基于对象(Object)和事件驱动(Event Driven)并具有相对安全性的客户端脚本语言。同时也是一种广泛用于客户端Web开发的脚本语言,常用来给HTML网页添加动态功能,比如响应用户的各种操作。它是一种动态、弱类型、基于原型的语言,内置支持类,做Web开发应该是常用的技术。
(2).Silverlight
Silverlight是一个跨浏览器的、跨平台的插件,是基于NET FrameWork的媒体体验和丰富的交互式应用程序。Silverlight提供灵活的编程模型,并可以很方便地集成到现有的网络应用程序中。Silverlight可以对运行在Mac或Windows上的主流浏览器提供高质量视频信息的快速、低成本的传递,一种富客户端技术。
2.简单理解SL与JS交互
Silverlight与JavaScript交互操作可分为两种:JavaScript操作Silverlight和Silverlight操作JavaScript,可能理解不是很到位,欢迎补充。
(1).对于JavaScript操作Silverlight的理解
使用浏览器桥对象可以分两步来处理:
A.在服务端页面加载完毕将Silverlight注册成宿主HTML页可进行脚本调用对象。
(需指定调用Silverlight插件的ScriptKey以及指定服务端公开接口,供JavaScript对象调用)
B.在客户端找到调用的Silverlight对象,调用服务端相关对象和接口操作数据。
(还是Silverght机制编写逻辑,只是开放服务端接口,供JavaScript调用执行不同数据操作)
(2).对于Silverlight操作JavaScript的理解
A.在客户端定义JavaScript的相关JS函数方法操作。
B.在服务端通过Silverlight封装的对象获取客户端的JS函数,执行不同的脚本操作。
(使用 HtmlPage.Window.GetProperty获取客户端的JS函数,执行InvokeSelf传递参数操作JS函数)
3.示例Demo演示
这里不介绍如何创建一个Silverlight程序,感兴趣的话可以查查相关资料,使用VS2010新建项目选择Silverlight应用程序就可以。
(1).Demo效果图展示
简单介绍一下这个Demo,Demo效果图如下:
这里的使用Div布局将页面切成2大块,左边的数据操作,右边的BingMap的展示(是用来展示SL操作JS的实现动态切换)。
左侧是Silverlight效果,整体使用Grid分配布局,使用三个Border布局进行不同的数据展示,数据采用数据模版绑定,左侧下面是一个按钮操作Div(是用来展示JS操作SL的数据实现动态加载)
(2).Demo代码
1).Silverlihgt项目Web项目中宿主ASPX页面HTML代码:(也可放在宿主HTML页面中)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <%@ Page Language="C#" AutoEventWireup="true" %> 2 3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 4 <html xmlns="http://www.w3.org/1999/xhtml" > 5 <head runat="server"> 6 <title>SilverlightDOM</title> 7 <style type="text/css"> 8 html, body { 9 height: 100%; 10 overflow: auto; 11 } 12 body { 13 padding: 0; 14 margin: 0; 15 } 16 #silverlightControlHost { 17 height: 90%; 18 text-align:center; 19 } 20 </style> 21 <script type="text/javascript" src="Silverlight.js"></script> 22 <!--中文支持http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2&mkt=zh-cn--> 23 <script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2" ></script> 24 <script type="text/javascript"> 25 function onSilverlightError(sender, args) { 26 var appSource = ""; 27 if (sender != null && sender != 0) { 28 appSource = sender.getHost().Source; 29 } 30 31 var errorType = args.ErrorType; 32 var iErrorCode = args.ErrorCode; 33 34 if (errorType == "ImageError" || errorType == "MediaError") { 35 return; 36 } 37 38 var errMsg = "Silverlight 应用程序中未处理的错误 " + appSource + "\n" ; 39 40 errMsg += "代码: "+ iErrorCode + " \n"; 41 errMsg += "类别: " + errorType + " \n"; 42 errMsg += "消息: " + args.ErrorMessage + " \n"; 43 44 if (errorType == "ParserError") { 45 errMsg += "文件: " + args.xamlFile + " \n"; 46 errMsg += "行: " + args.lineNumber + " \n"; 47 errMsg += "位置: " + args.charPosition + " \n"; 48 } 49 else if (errorType == "RuntimeError") { 50 if (args.lineNumber != 0) { 51 errMsg += "行: " + args.lineNumber + " \n"; 52 errMsg += "位置: " + args.charPosition + " \n"; 53 } 54 errMsg += "方法名称: " + args.methodName + " \n"; 55 } 56 57 引发新错误(errMsg); 58 } 59 </script> 60 <script type="text/javascript" language="javascript"> 61 //其实这里浏览器桥(JS操作SL数据),涉及两部分: 62 //1.服务端注册Silverlight对象的Name和开放的脚本接口 63 //2.客户端Silverlight对象指定的服务端桥接对象调用服务端开放脚本接口 64 //其根本对Silverlight数据操作仍是Silverlight的操作,只是提供了接口操作者转接到HTML中 65 function sliverlightServerData(country) { 66 //获取页面的Silverlight对象 67 var slPlugin = document.getElementById("sliverlightObject"); 68 //使用Silverlight对象指定的服务端Name,通过Name调用开放的接口 69 slPlugin.Content.SilverlightName.GetCitiesByCountry(country); 70 } 71 </script> 72 <script type="text/javascript" language="javascript"> 73 //Silverlight操作JavaScript数据 74 //JS获取Bing Maps API 75 var map = null; 76 77 //获取BingMap地图 78 function getBingMap() { 79 map = new VEMap('divMap'); 80 map.LoadMap(); 81 } 82 83 //移动地图 84 //传入地区名称,定位地图位置 85 function moveMap(where) { 86 try { 87 map.Find(null, where); 88 } 89 catch (e) { 90 alert(e.Message); 91 } 92 } 93 </script> 94 </head> 95 <body onload="getBingMap()"> 96 <form id="form1" runat="server"> 97 <div style=" height:400px; margin:10px 5px 0px 10px"> 98 <!--左侧Div--> 99 <div id="silverlightControlHost" style="float:left; height:92%; width:25%; border:1px solid purple"> 100 <object id="sliverlightObject" data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"> 101 <param name="source" value="ClientBin/SilverlightDOM.xap"/> 102 <param name="onError" value="onSilverlightError" /> 103 <param name="background" value="white" /> 104 <param name="minRuntimeVersion" value="4.0.60310.0" /> 105 <param name="autoUpgrade" value="true" /> 106 <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.60310.0" style="text-decoration:none"> 107 <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="获取 Microsoft Silverlight" style="border-style:none"/> 108 </a> 109 </object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe> 110 <!--按钮触发操作JavaScript操作Silverlight数据--> 111 <div style="width:100%;height:8%;background-color:Orange; border:1px solid blue; text-align:left; vertical-align:middle"> 112 <input type="button" value="英国" onclick="sliverlightServerData(this.value)" /> 113 <input type="button" value="德国" onclick="sliverlightServerData(this.value)" /> 114 <input type="button" value="法国" onclick="sliverlightServerData(this.value)" /> 115 <input type="button" value="中国" onclick="sliverlightServerData(this.value)" /> 116 </div> 117 </div> 118 <!--右侧Bing Maps展示,注意上面Bing Maps地址脚本的引入--> 119 <div id="divMap" style=" float:left; position:relative; width:74%; height:100%; margin:0px auto 0px auto; z-index:2; border:1px solid purple" ></div> 120 </div> 121 </form> 122 </body> 123 </html>
2).Silverlight项目MainPage.xaml页面代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <UserControl x:Class="SilverlightDOM.MainPage" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 mc:Ignorable="d" 7 d:DesignHeight="300" d:DesignWidth="500" Loaded="UserControl_Loaded"> 8 9 <!--定义样式--> 10 <UserControl.Resources> 11 <Style x:Name="borderStyle" TargetType="Border"> 12 <Setter Property="BorderBrush" Value="Green"/> 13 <Setter Property="BorderThickness" Value="2"/> 14 </Style> 15 </UserControl.Resources> 16 17 <Grid x:Name="LayoutRoot" Background="White" Loaded="LayoutRoot_Loaded"> 18 <!--Grid行定义--> 19 <Grid.RowDefinitions> 20 <RowDefinition Height="25"></RowDefinition> 21 <RowDefinition Height="50"></RowDefinition> 22 <RowDefinition Height="50"></RowDefinition> 23 <RowDefinition Height="50"></RowDefinition> 24 <RowDefinition Height="50"></RowDefinition> 25 <RowDefinition Height="*"></RowDefinition> 26 </Grid.RowDefinitions> 27 <TextBlock Grid.Row="0" FontSize="15" Foreground="Purple">点击选择按钮定位地图位置:</TextBlock> 28 <Border Grid.Row="1" Grid.RowSpan="2" Style="{StaticResource borderStyle}"> 29 <StackPanel Orientation="Vertical"> 30 <TextBlock FontSize="15" Foreground="Purple">UserControlLoad加载数据:</TextBlock> 31 <!--ItemsControl数据源绑定显示--> 32 <ItemsControl x:Name="itemCities"> 33 <ItemsControl.ItemTemplate> 34 <DataTemplate> 35 <!--绑定数据--> 36 <StackPanel Orientation="Horizontal" Height="25"> 37 <CheckBox Checked="CheckBox_Checked" Content="{Binding CityName}"></CheckBox> 38 <TextBlock><Run>(</Run><Run>纬度:</Run></TextBlock> 39 <TextBlock Foreground="Purple" Text="{Binding CityLatitude}"/> 40 <TextBlock>)</TextBlock> 41 </StackPanel> 42 </DataTemplate> 43 </ItemsControl.ItemTemplate> 44 </ItemsControl> 45 </StackPanel> 46 </Border> 47 <Border Grid.Row="3" Grid.RowSpan="2" Style="{StaticResource borderStyle}" BorderThickness="2,0,2,2"> 48 <StackPanel Orientation="Vertical"> 49 <TextBlock FontSize="15" Foreground="Purple">浏览器桥开放JavaScript接口数据:</TextBlock> 50 <!--ItemsControl数据源绑定显示--> 51 <ItemsControl x:Name="itemHtmlOper"> 52 <ItemsControl.ItemTemplate> 53 <DataTemplate> 54 <StackPanel Orientation="Horizontal" Height="25" > 55 <RadioButton GroupName="GroupCities" Checked="RadioButton_Checked" Content="{Binding CityName}"/> 56 <TextBlock>(纬度:</TextBlock> 57 <TextBlock Text="{Binding CityLatitude}" /> 58 <TextBlock>)</TextBlock> 59 </StackPanel> 60 </DataTemplate> 61 </ItemsControl.ItemTemplate> 62 </ItemsControl> 63 </StackPanel> 64 </Border> 65 <Border Grid.Row="5" Style="{StaticResource borderStyle}" BorderThickness="2,0,2,2"> 66 <StackPanel Orientation="Vertical"> 67 <TextBlock FontSize="15" Foreground="Purple">ListBox数据绑定测试:</TextBlock> 68 <!--ListBox数据源绑定显示--> 69 <ListBox Name="listCities" > 70 <ListBox.ItemTemplate> 71 <DataTemplate> 72 <StackPanel Orientation="Horizontal" > 73 <CheckBox IsChecked="True" Content="{Binding CityName}"> 74 <CheckBox.RenderTransform><!--CheckBox缩放居中--> 75 <ScaleTransform ScaleX="1.2" ScaleY="1.2" CenterX="1" CenterY="1"/> 76 </CheckBox.RenderTransform> 77 </CheckBox> 78 <TextBlock FontSize="13" Text=" 旅游景点:"/> 79 <ComboBox Width="100" ItemsSource="{Binding CityAttractions}"/> 80 </StackPanel> 81 </DataTemplate> 82 </ListBox.ItemTemplate> 83 </ListBox> 84 </StackPanel> 85 </Border> 86 </Grid> 87 </UserControl>View Code
3).Silverlight项目MainPage.xaml.cs代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Net; 5 using System.Windows; 6 using System.Windows.Controls; 7 using System.Windows.Documents; 8 using System.Windows.Input; 9 using System.Windows.Media; 10 using System.Windows.Media.Animation; 11 using System.Windows.Shapes; 12 using System.Windows.Browser; 13 using System.Windows.Media.Imaging; 14 15 namespace SilverlightDOM 16 { 17 public partial class MainPage : UserControl 18 { 19 public MainPage() 20 { 21 InitializeComponent(); 22 } 23 24 25 private void LayoutRoot_Loaded(object sender, RoutedEventArgs e) 26 { 27 //ThreadTest();//线程分配测试 28 29 string strCountry = "中国"; 30 this.itemCities.ItemsSource = GetQueryData(strCountry);//绑定数据 31 this.listCities.ItemsSource = GetQueryData(strCountry);//绑定数据 32 } 33 /// <summary> 34 /// 注册Silvelight为脚本调用对象 35 /// JavaScript调用Silverlight对象 36 /// </summary> 37 /// <param name="sender"></param> 38 /// <param name="e"></param> 39 private void UserControl_Loaded(object sender, RoutedEventArgs e) 40 { 41 //HtmlDomOper();//HTML DOM操作 42 43 //浏览器桥,进行HTML与Silverlight交互,以及浏览器端开放的接口GetCitiesByCountry 44 //页面加载完成,将Silverlight注册成宿主HTML页上可进行脚本处理对象 45 //使用下面的方式注册脚本对象,第一个参数指定名称 46 HtmlPage.RegisterScriptableObject("SilverlightName", this); 47 } 48 49 /// <summary> 50 /// 初始化数据 51 /// </summary> 52 /// <returns></returns> 53 private List<CityData> InitData() 54 { 55 List<CityData> listCityData = new List<CityData>() { 56 new CityData(){CityName="北京",CityLatitude=23, CityAttractions=new List<string>(){"故宫","鸟巢","天安门"}}, 57 new CityData(){CityName="济南",CityLatitude=45, CityAttractions=new List<string>(){"趵突泉","大明湖","千佛山"}}, 58 new CityData(){CityName="深圳",CityLatitude=90,CityAttractions=new List<string>(){"欢乐谷","世界之窗","海上田园"}} 59 }; 60 61 return listCityData; 62 } 63 64 /// <summary> 65 /// 查询城市信息 66 /// </summary> 67 /// <param name="queryCondition">所在国家</param> 68 /// <returns>该国家城市信息集合</returns> 69 private List<CityData> GetQueryData(string queryCondition) 70 { 71 List<CityData> queryList = new List<CityData>(); 72 switch (queryCondition) 73 { 74 case "中国": queryList = InitData(); break; 75 case "法国": 76 queryList.Add(new CityData("巴黎", 12.6, 45));//巴黎 Paris 77 queryList.Add(new CityData("卢尔德", 35.5, 66.6));//卢尔德 lourdes 78 queryList.Add(new CityData("图卢兹", 55.3, 66.5));//图卢兹 Toulouse 79 break; 80 case "英国": 81 queryList.Add(new CityData("伦敦",33.3,45.5)); 82 queryList.Add(new CityData("爱丁堡",77.8,88.9)); 83 break; 84 case "德国": 85 CityData[] cityArray = new CityData[] { 86 new CityData("柏林",33.3,66.6), 87 new CityData("汉堡",99.8,88.9), 88 new CityData("慕尼黑",56.6,67.8) 89 }; 90 queryList = cityArray.ToList(); 91 break; 92 default: queryList = null; break; 93 } 94 95 return queryList; 96 } 97 98 /// <summary> 99 /// 对于HTML与Silverlight进行交互 100 /// 使用ScriptableMember表示对外部调用者公开的方法 101 /// </summary> 102 /// <param name="country"></param> 103 [ScriptableMember] 104 public void GetCitiesByCountry(string country) 105 { 106 List<CityData> listCities = GetQueryData(country); 107 itemHtmlOper.ItemsSource = listCities; 108 } 109 110 /// <summary> 111 /// 模版数据绑定,CheckBox按钮选中事件 112 /// Silverlight操作JavaScript数据 113 /// </summary> 114 /// <param name="sender"></param> 115 /// <param name="e"></param> 116 private void CheckBox_Checked(object sender, RoutedEventArgs e) 117 { 118 string strCityName = string.Empty; 119 CheckBox chkBox = sender as CheckBox; 120 if (chkBox.IsChecked == true) 121 { 122 strCityName = chkBox.Content.ToString(); 123 124 //Silverlight获取JS函数,使用HtmlPage.Window.GetProperty("函数名"),转化为ScriptObject对象 125 //使用转化的ScriptObjcet对象的InvokeSelf(线程处理),调用自己脚本函数传递参数(可选) 126 ScriptObject scriptObject = HtmlPage.Window.GetProperty("moveMap") as ScriptObject; 127 scriptObject.InvokeSelf(strCityName); 128 } 129 } 130 131 /// <summary> 132 /// 模版数据绑定,RadioButton按钮选中事件 133 /// </summary> 134 /// <param name="sender"></param> 135 /// <param name="e"></param> 136 private void RadioButton_Checked(object sender, RoutedEventArgs e) 137 { 138 string strCityName = string.Empty; 139 RadioButton rbButton = sender as RadioButton; 140 strCityName = rbButton.Content.ToString(); 141 142 ScriptObject scriptObject = HtmlPage.Window.GetProperty("moveMap") as ScriptObject; 143 scriptObject.InvokeSelf(strCityName); 144 } 145 146 /// <summary> 147 /// 对HTML DOM操作支持 148 /// </summary> 149 private void HtmlDomOper() 150 { 151 //System.Windows.Browser.HtmlPage.Window; 152 //System.Windows.Browser.HtmlPage.Document; 153 //System.Windows.Browser.HtmlPage.Plugin; 154 //System.Windows.Browser.BrowserInformation; 155 //System.Windows.Browser.HtmlDocument; 156 //System.Windows.Browser.HtmlElement; 157 //System.Windows.Browser.HtmlEventArgs; 158 159 System.Windows.Browser.HtmlPage.Window.Alert("Web Alert 信息提示!"); 160 System.Windows.Browser.HtmlPage.Window.Eval("alert('Web Eval JS脚本信息提示!');");//Eval接受脚本函数语法 161 bool confirm = HtmlPage.Window.Confirm("Web Confirm 确认删除吗?"); 162 if (confirm) { HtmlPage.Window.Alert("你点击了确认!"); } else { HtmlPage.Window.Eval("alert('你点击了取消!');"); } 163 string promptInfo = HtmlPage.Window.Prompt("Web Prompt信息提示填入!"); 164 165 string parentID = HtmlPage.Plugin.Parent.Id; 166 HtmlElement htmlElement = HtmlPage.Document.GetElementById(parentID);//button1 167 string style = htmlElement.GetAttribute("style"); 168 HtmlPage.Window.Alert(parentID + "|" + style); 169 } 170 171 /// <summary> 172 /// 线程分配测试 173 /// </summary> 174 private void ThreadTest() 175 { 176 MessageBox.Show("主线程1!"); 177 Deployment.Current.Dispatcher.BeginInvoke(delegate 178 { 179 MessageBox.Show("开辟线程1,线程Sleep 500!"); System.Threading.Thread.Sleep(500); 180 Deployment.Current.Dispatcher.BeginInvoke(delegate { MessageBox.Show("线程嵌套1!"); }); 181 Deployment.Current.Dispatcher.BeginInvoke(delegate { MessageBox.Show("线程嵌套2!"); }); 182 }); 183 MessageBox.Show("主线程2!"); 184 Deployment.Current.Dispatcher.BeginInvoke(delegate { MessageBox.Show("开辟线程2,线程Sleep 1000!"); System.Threading.Thread.Sleep(1000); }); 185 MessageBox.Show("主线程3!"); 186 Deployment.Current.Dispatcher.BeginInvoke(delegate { MessageBox.Show("开辟线程3!"); }); 187 } 188 } 189 190 /// <summary> 191 /// 数据结构 192 /// </summary> 193 public class CityData 194 { 195 public CityData() { } 196 197 public CityData(string cityName,double cityLatitude,double cityLongitude) 198 { 199 CityName = cityName; 200 CityLatitude = cityLatitude; 201 CityLongitude = cityLongitude; 202 } 203 204 public string CityName { get; set; } 205 public double CityLatitude { get; set; } 206 public double CityLongitude { get; set; } 207 public List<string> CityAttractions { get; set; } 208 } 209 }
(3).Demo代码简说
1).对于宿主页面注意:BingMaps脚本地址引入及其布局调整
2).对于MainPage.XAML页面布局
3).对于MainPage.xaml.cs
比较简单容易理解,对于Silverlight和JavaScript交互有更好理解的欢迎交流。