一步一步学Silverlight 2系列(22):在Silverlight中如何用JavaScript调用.NET代码

概述

Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, Ironpython,对JSON、Web Service、WCF以及Sockets的支持等一系列新的特性。《一步一步学Silverlight 2系列》文章将从Silverlight 2基础知识、数据与通信、自定义控件、动画、图形图像等几个方面带您快速进入Silverlight 2开发。

Silverlight中内置了对于HTML、客户端脚本等的支持。上一篇介绍在Silverlight中调用JavaScript,本文我将介绍在Silverlight中如何用JavaScript调用.NET代码。

使用RegisterScriptableObject

在Silverlight 2中提供了如下两个类型:

ScriptableMemberAttribute:允许我们在Silverlight把成员暴露给Script。

ScriptableTypeAttribute:允许我们在Silverlight把类型暴露给Script。

同时HtmlPage提供了RegisterCreateableType和RegisterScriptableObject方法,用来注册可被脚本使用的类型或者对象实例。有了上面这些,就可以做到在JavaScript中调用Silverlight。

看一个简单的示例,在这个示例中,我们期望通过JavaScript传递两个参数给Silverlight中的方法,由该方法计算出结果后显示在Silverlight中,如图所示:

TerryLee_Silverlight2_0103 

首先我们编写在Silverlight中的界面布局:

<StackPanel Background="#CDFCAE" Orientation="Horizontal">
    <Border CornerRadius="10" Width="100" Height="40" Margin="50 10 0 0">
        <TextBlock Text="结果显示:" FontSize="20" Foreground="Red"></TextBlock>
    </Border>
    <Border CornerRadius="10" Background="Green" Width="300" Height="40">
        <TextBlock x:Name="result" FontSize="20" Foreground="White"
                   Margin="20 5 0 0"></TextBlock>
    </Border>
</StackPanel> 

并在加载时注册一个脚本可调用的当前页面实例:

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    HtmlPage.RegisterScriptableObject("Calculator", this);
}

编写一个Add方法,该方法将在JavaScript中被调用,必须为public,用ScriptableMember特性暴露给脚本。

[ScriptableMember]
public void Add(int x, int y)
{
    int z = x + y;
    this.result.Text = String.Format("{0} + {1} = {2}", x, y, z);
}

现在编写测试页中的内容,提供输入的input控件:

<div class="main">
    <input id="txt1" type="text" />
    <input id="txt2" type="text" />
    <input id="Button1" type="button" value="确 定"/>
</div>

编写JavaScript调用Silverlight中的方法,获取Silverlight插件,Calculator就是我们刚才所注册的实例:

<script type="text/javascript">
    function callSilverlight()
    {
        var slPlugin = $get('Xaml1');
        
        slPlugin.content.Calculator.Add($get('txt1').value,$get('txt2').value);
    }
</script>

在按钮单击事件中调用该方法

<input id="Button1" type="button" value="确 定" onclick="callSilverlight()" />

运行后结果:

TerryLee_Silverlight2_0103 

输入两个数后显示出结果:

 TerryLee_Silverlight2_0104

使用RegisterCreateableType

现在我们再看一下如何使用RegisterCreateableType。对上面的示例做一些简单的改动,在Silverlight项目中添加一个Calculator类,需要给它加上ScriptableType特性:

[ScriptableType]
public class Calculator
{
    [ScriptableMember]
    public int Add(int x, int y)
    {
        return x + y;
    }
}

在页面加载时修改为如下代码,指定一个别名和要注册的类型:

HtmlPage.RegisterCreateableType("calculator", typeof(Calculator));

这样在JavaScript中就可以这样进行调用了,先创建一个之前注册为ScriptableType的实例,再调用它的相关方法:

<script type="text/javascript">
    function callSilverlight()
    {
        var slPlugin = $get('Xaml1');
        var cal = slPlugin.content.services.createObject("calculator");
        
        alert(cal.Add($get('txt1').value,$get('txt2').value));
    }
</script>

运行结果如下,没有问题:

TerryLee_Silverlight2_0105 

结束语

本文介绍了如何在JavaScript中调用Silverlight,通过前面几篇文章的介绍,如对DOM的操作、在Silverlight中调用JavaScript、在JavaScript中调用Silverlight等,可以看到,Silverlight与浏览器之间交互有着很好的支持,后面将继续介绍其它内容。

作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
Tag标签: Silverlight
posted @ 2008-03-13 17:47 TerryLee 阅读(8041) 评论(49)  编辑 收藏 网摘 所属分类: [03]  银光点亮世界

  回复  引用  查看    
#1楼2008-03-13 17:55 | 菜菜灰      
沙发
  回复  引用  查看    
#2楼[楼主]2008-03-13 17:56 | TerryLee      
@菜菜灰
:)

  回复  引用    
#3楼2008-03-13 17:57 | JeffreyChen[未注册用户]
速度太快了,明天再来学习,下班了,呵...
  回复  引用  查看    
#4楼2008-03-13 17:58 | jillzhang      
学习的都不如你写的快了,太强了
  回复  引用  查看    
#5楼[楼主]2008-03-13 18:02 | TerryLee      
@JeffreyChen
@jillzhang
谢谢两位的支持:)

  回复  引用  查看    
#6楼2008-03-13 18:03 | 阿布      
:D
  回复  引用  查看    
#7楼2008-03-13 18:08 | neuhawk      
比较关心
1,右键
2,打印

  回复  引用  查看    
#8楼2008-03-13 18:09 | 永春      
佩服,忒快了
  回复  引用  查看    
#9楼[楼主]2008-03-13 18:25 | TerryLee      
@阿布
:)

  回复  引用  查看    
#10楼[楼主]2008-03-13 18:25 | TerryLee      
@neuhawk
右键现在似乎不好实现

  回复  引用  查看    
#11楼[楼主]2008-03-13 18:26 | TerryLee      
@永春
:)

  回复  引用  查看    
#12楼2008-03-13 18:30 | youhok      
学习!

目前正在用 sl 做一个关系图程序,也是打印问题没有眉目。
右键菜单可以用 canvas模拟吧,似乎没太好的办法,希望尽快能出来弹出菜单的控件。

  回复  引用    
#13楼2008-03-13 18:50 | 5254341[未注册用户]
--引用--------------------------------------------------
jillzhang: 学习的都不如你写的快了,太强了
--------------------------------------------------------
是呀,老大真是太强了

  回复  引用  查看    
#14楼[楼主]2008-03-13 19:04 | TerryLee      
@youhok
现在右键菜单确实没有很好的方法

  回复  引用  查看    
#15楼[楼主]2008-03-13 19:05 | TerryLee      
@5254341
:)

在搭配上DLR就更酷,在页面上现在用多种语言混合编码操纵页面的DOM,包括javascript,ironpython,ironruby,vbx,ManagedJs. 可看看这个项目http://www.codeplex.com/DLRScript
  回复  引用  查看    
#17楼2008-03-14 08:02 | 生鱼片      
支持
  回复  引用  查看    
#18楼2008-03-14 08:14 | 小庄      
打印是个问题;多窗口管理也是个问题,客户端代码动态下载并运行更是个问题!搞个sl做的windows desktop还有很多问题要解决啊!
  回复  引用  查看    
#19楼[楼主]2008-03-14 08:36 | TerryLee      
@自由、创新、研究、探索……
有空看看这个项目,呵呵,多谢:)

  回复  引用  查看    
#20楼[楼主]2008-03-14 08:37 | TerryLee      
@生鱼片
谢谢:)

  回复  引用  查看    
#21楼[楼主]2008-03-14 08:37 | TerryLee      
@小庄
多窗口是不是可以通过加载UserControl来模拟。。。

  回复  引用  查看    
#22楼2008-03-14 09:22 | 闲蚁      
请问一下楼主, 我在用Application.GetResourceStream方法获取Build action为Resource的文件时为什么老是返回null, 看了MSDN上说相对路径要用"SilverlightApplication;component/test.txt",还是不行,只有build action为content的才获取得到,楼主能不能帮忙看一下, :)
  回复  引用  查看    
#23楼2008-03-14 11:11 | 状元      
想问一下,
我要是部署到买的空间上,
需要空间支持silverlight
还是说只要普通的空间就行?

  回复  引用  查看    
#24楼2008-03-14 13:38 | Scott Xu(南方小鬼)      
有个问题请教一下,现在有两个页面A和B,A以POST方式提交给B,B页面中的SL如何获得提交过来的FORM?
  回复  引用  查看    
#26楼[楼主]2008-03-14 22:52 | TerryLee      
@闲蚁
我有空测试一下吧,我没注意这一点:)

  回复  引用  查看    
#27楼[楼主]2008-03-14 22:52 | TerryLee      
@状元
现在打包为xap文件,似乎普通的就行吧,应该跟flash差不多

  回复  引用  查看    
#28楼[楼主]2008-03-14 22:53 | TerryLee      
@Scott Xu(南方小鬼)
用WebRequest应该可以吧

  回复  引用  查看    
#29楼2008-03-16 18:30 | 状元      
@TerryLee
谢谢!

  回复  引用  查看    
#30楼[楼主]2008-03-16 23:29 | TerryLee      
@状元
不过提供空间的IIS服务器应该设置一下对.xap文件的处理.

  回复  引用  查看    
#31楼2008-03-26 15:46 | 东吴居士      
请问楼主sl在firefox中文字体显示不出来如何解决?
What is this line:
var cal = slPlugin.content.services.createObject("calculator");

"services" is not registered anywhere.. so I get invalid alias found, and the example does not work.

  回复  引用  查看    
#33楼2008-05-18 16:09 | 吴博      
第一个例子试验失败。
在测试页中“slPlugin”为[object],“slPlugin.content”为undefined。

有本篇教程源码下载吗?

  回复  引用    
#34楼2008-06-11 15:38 | Helloword[未注册用户]
今天才发现,有点 XXX的感觉。
已经天天看。写的太棒了

  回复  引用    
#35楼2008-07-07 19:09 | richardyjj[未注册用户]
请问如何在SL中触发控件打开一个新的窗口,HtmlPage.Window.Navigate(new Uri(XXX),"new")是否可行,如果可行那如何在SL与新窗口间进行数据传递呢,例如打开的page是个form,如何在submit之后将参数传回SL
  回复  引用  查看    
#36楼[楼主]2008-07-08 16:17 | TerryLee      
@吴博
有空把代码发给我,看一下

  回复  引用  查看    
#37楼[楼主]2008-07-08 16:17 | TerryLee      
@Helloword
:)

  回复  引用  查看    
#38楼[楼主]2008-07-08 16:24 | TerryLee      
@richardyjj
SL与页面之间的传参有很多种方式,可以使用InitParams或者QueryString等。

  回复  引用  查看    
#39楼2008-07-31 10:30 | monkey-猴子      
--引用--------------------------------------------------
吴博: 第一个例子试验失败。
<br>在测试页中“slPlugin”为[object],“slPlugin.content”为undefined。
<br>
<br>有本篇教程源码下载吗?
--------------------------------------------------------
我遇到的也是这个问题,请问楼主这个问题怎么解决的哈?

  回复  引用  查看    
#40楼[楼主]2008-08-01 00:52 | TerryLee      
@monkey-猴子
var slPlugin = $get('Xaml1');
看看这里,Silverlight控件的ID是否正确

  回复  引用  查看    
#41楼2008-10-13 15:32 | threeG      
并在加载时注册一个脚本可调用的当前页面实例:

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
HtmlPage.RegisterScriptableObject("Calculator", this);
}

这段代码下在哪里啊?谢谢啊!

  回复  引用    
#42楼2008-11-13 00:36 | 冻结[未注册用户]
@threeG
直接写在构造函数Page里就可以,或者:
public Page()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(Page_Loaded);
}

void Page_Loaded(object sender, RoutedEventArgs e)
{
// 写在这里
}




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1104110




历史上的今天:
2006-03-13 .NET Pet Shop 4.0案例研究预览篇

相关文章:

相关链接: