随笔 - 616, 文章 - 0, 评论 - 10492
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
[索引页]
[源码下载]


稳扎稳打Silverlight(27) - 2.0网页之可脚本化, 与DOM的交互, 与JavaScript的交互


作者:webabcd


介绍
Silverlight 2.0 使用c#开发可脚本化的代码,Silverlight与宿主页面的DOM之间的交互,Silverlight与宿主页面的JavaScript之间的交互
    ScriptableMemberAttribute - 需要脚本化的属性、方法、事件要标记为此
    HtmlPage.RegisterScriptableObject - 将可脚本化对象注册到客户端
    HtmlElement -  表示网页的文档对象模型 (DOM) 中的 HTML 元素
    HtmlWindow - 提供 JavaScript 的 window 对象的 Silverlight 端的托管表示形式


在线DEMO
http://www.cnblogs.com/webabcd/archive/2008/10/09/1307486.html


示例
1、Silverlight对可脚本化的支持
Scriptable.cs
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using System.Windows.Browser;

namespace Silverlight20.WebPage
{
    
/*
     * 脚本化的类必须是 public 的
     * 需要脚本化的属性、方法、事件要标记为 [ScriptableMember]
     * 如果类被标记为 [ScriptableType],则意味着其属性、方法、事件都是ScriptableMemberAttribute
     
*/


    
/// <summary>
    
/// 用于演示脚本化的类
    
/// </summary>

    // [ScriptableType]
    public class Scriptable
    
{
        
/// <summary>
        
/// 当前服务端的时间
        
/// </summary>

        [ScriptableMember]
        
public DateTime CurrentTime getset; }

        
/// <summary>
        
/// Hello 方法
        
/// </summary>
        
/// <param name="name">名字</param>
        
/// <returns></returns>

        [ScriptableMember]
        
public string Hello(string name)
        
{
            
return string.Format("Hello: {0}", name);
        }

        
        
/// <summary>
        
/// 开始事件
        
/// </summary>

        [ScriptableMember]
        
public event EventHandler<StartEventArgs> Start;

        
/// <summary>
        
/// 触发开始事件所调用的方法
        
/// </summary>
        
/// <param name="dt"></param>

        public void OnStart(DateTime dt)
        
{
            
if (Start != null)
            
{
                Start(
thisnew StartEventArgs()
                
{
                    CurrentTime 
= dt
                }
);
            }

        }


    }


    
/// <summary>
    
/// 开始事件的 EventArgs
    
/// </summary>

    public class StartEventArgs : EventArgs
    
{
        
/// <summary>
        
/// 当前服务端的时间
        
/// </summary>

        [ScriptableMember]
        
public DateTime CurrentTime getset; }
    }

}


ScriptableDemo.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using System.Windows.Browser;

namespace Silverlight20.WebPage
{
    
public partial class ScriptableDemo : UserControl
    
{
        System.Threading.Timer _timer;
        System.Threading.SynchronizationContext _syncContext;

        
public ScriptableDemo()
        
{
            InitializeComponent();

            
this.Loaded += new RoutedEventHandler(ScriptableDemo_Loaded);
        }


        
void ScriptableDemo_Loaded(object sender, RoutedEventArgs e)
        
{
            
// UI 线程
            _syncContext = System.Threading.SynchronizationContext.Current;

            Scriptable s 
= new Scriptable() { CurrentTime = DateTime.Now };

            
// 将 Scriptable 对象注册到客户端中,所对应的客户端的对象名为 scriptable
            HtmlPage.RegisterScriptableObject("scriptable", s);

            _timer 
= new System.Threading.Timer(MyTimerCallback, s, 01000);
        }


        
private void MyTimerCallback(object state)
        
{
            Scriptable s 
= state as Scriptable;

            
// 每秒调用一次 UI 线程上的指定的方法
            _syncContext.Post(OnStart, s);
        }


        
void OnStart(object state)
        
{
            Scriptable s 
= state as Scriptable;

            
// 调用 Scriptable 对象的 OnStart() 方法,以触发 Start 事件
            s.OnStart(DateTime.Now);
        }

    }

}


ScriptableDemo.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>Silverlight20</title>
    
<style type="text/css">
        html, body
        
{
            height
: 100%;
            overflow
: auto;
        
}

        body
        
{
            padding
: 0;
            margin
: 0;
        
}

        #silverlightControlHost
        
{
            height
: 100%;
        
}

    
</style>

    
<script type="text/javascript" src="../Silverlight.js"></script>

    
<script type="text/javascript">
        
function scriptableDemo() {

            
// scriptable - Silverlight 注册到客户端的对象
            var obj = document.getElementById("xaml1").content.scriptable;
            
var output = document.getElementById('result');

            output.innerHTML 
+= obj.CurrentTime
            output.innerHTML 
+= '<br />';

            output.innerHTML 
+= obj.Hello("webabcd");
            output.innerHTML 
+= '<br />';

            
// obj.Start = responseStart;
            // addEventListener - 添加事件监听器
            // removeEventListener - 移除事件监听器
            obj.addEventListener("Start", responseStart);
        }


        
function responseStart(sender, args) {
            document.getElementById(
'result').innerHTML += args.CurrentTime;
            document.getElementById(
'result').innerHTML += '<br />';
        }

    
</script>

</head>
<body>
    
<div style="font-size: 12px" id="result">
    
</div>
    
<div style="font-size: 12px" onclick="scriptableDemo();">
        加载了 Silverlight20.WebPage.ScriptableDemo 后,单击这里以测试 Silverlight 对可脚本化的支持
</div>
    
<div id="silverlightControlHost">
        
<object id="xaml1" data="data:application/x-silverlight-2," type="application/x-silverlight-2"
            width
="100%" height="100%">
            
<param name="source" value="../ClientBin/Silverlight20.xap" />
            
<param name="EnableHtmlAccess" value="true" />
        
</object>
        
<iframe style='visibility: hidden; height: 0; width: 0; border: 0px'></iframe>
    
</div>
</body>
</html>


2、Silverlight与网页的DOM之间的交互
DOMDemo.xaml
<UserControl x:Class="Silverlight20.WebPage.DOMDemo"
    xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml">
    
<StackPanel HorizontalAlignment="Left" Margin="5">

        
<TextBox x:Name="txtMsg" />
        
    
</StackPanel>
</UserControl>

DOMDemo.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using System.Windows.Browser;

namespace Silverlight20.WebPage
{
    
public partial class DOMDemo : UserControl
    
{
        
public DOMDemo()
        
{
            InitializeComponent();

            Demo();
        }


        
void Demo()
        
{
            
// 获取当前页面的 id 为 hello 的DOM,并设置其样式
            HtmlElement container = HtmlPage.Document.GetElementById("hello");
            container.SetStyleAttribute(
"display""block");

            
// 创建一个 ul 
            HtmlElement ul = HtmlPage.Document.CreateElement("ul");

            
for (int i = 0; i < 10; i++)
            
{
                
// 创建一个 li ,并设置其显示的内容
                HtmlElement li = HtmlPage.Document.CreateElement("li");
                li.SetAttribute(
"innerText""hi: DOM");

                
// 将 li 添加到 ul 内
                ul.AppendChild(li);
            }


            
// 将 ul 添加到 id 为 hello 的 DOM 内
            container.AppendChild(ul);


            
// 创建一个页面的 button ,并设置其 value 属性和 onclick 事件
            HtmlElement button = HtmlPage.Document.CreateElement("button");
            button.SetProperty(
"value""hi: Silverlight");
            button.AttachEvent(
"onclick"new EventHandler<HtmlEventArgs>(HelloClick));

            
// 将 button 添加到 id 为 hello 的 DOM 内
            container.AppendChild(button);
        }


        
void HelloClick(object sender, HtmlEventArgs e)
        
{
            
// 页面的 button 单击后所需执行的逻辑
            txtMsg.Text += "hi: Silverlight\r\n";
        }

    }

}


DOMDemo.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>Silverlight20</title>
    
<style type="text/css">
        html, body
        
{
            height
: 100%;
            overflow
: auto;
        
}

        body
        
{
            padding
: 0;
            margin
: 0;
        
}

        #silverlightControlHost
        
{
            height
: 100%;
        
}

    
</style>

    
<script type="text/javascript" src="../Silverlight.js"></script>

</head>
<body>
    
<!--由 Silverlight 控制此 id 为 hello 的 DOM-->
    
<div style="font-size: 12px; display: none" id="hello">
    
</div>
    
<div style="font-size: 12px">
        加载 Silverlight20.WebPage.DOMDemo 后,测试 Silverlight 和页面 DOM 的交互
</div>
    
<div id="silverlightControlHost">
        
<object id="xaml1" data="data:application/x-silverlight-2," type="application/x-silverlight-2"
            width
="100%" height="100%">
            
<param name="source" value="../ClientBin/Silverlight20.xap" />
            
<param name="EnableHtmlAccess" value="true" />
        
</object>
        
<iframe style='visibility: hidden; height: 0; width: 0; border: 0px'></iframe>
    
</div>
</body>
</html>


3、Silverlight与网页的JavaScript之间的交互
JSDemo.xaml
<UserControl x:Class="Silverlight20.WebPage.JSDemo"
    xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml">
    
<StackPanel HorizontalAlignment="Left" Margin="5">

        
<Button Margin="5" x:Name="invokeJS" Content="调用JavaScript" Click="invokeJS_Click" />
        
        
<TextBox Margin="5" x:Name="txtMsg" />

    
</StackPanel>
</UserControl>

JSDemo.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using System.Windows.Browser;

namespace Silverlight20.WebPage
{
    
public partial class JSDemo : UserControl
    
{
        
public JSDemo()
        
{
            InitializeComponent();

            
this.Loaded += new RoutedEventHandler(JSDemo_Loaded);
        }


        
private void invokeJS_Click(object sender, RoutedEventArgs e)
        
{
            
// 调用页面的 JavaScript 方法
            HtmlPage.Window.Invoke("silverlightInvokeJS""webabcd");

            
// 执行任意 JavaScript 语句
            HtmlPage.Window.Eval("silverlightInvokeJS('webabcd2')");
        }


        
void JSDemo_Loaded(object sender, RoutedEventArgs e)
        
{
            HtmlPage.Document.GetElementById(
"btnHello").SetStyleAttribute("display""inline");

            
// 将此对象注册到客户端中,所对应的客户端的对象名为 silverlightObject
            HtmlPage.RegisterScriptableObject("silverlightObject"this);
        }


        
/// <summary>
        
/// Hello 方法
        
/// 暴露给页面的方法,调用后在 Silverlight 中显示结果
        
/// </summary>
        
/// <param name="name">名字</param>

        [ScriptableMember] // 脚本化此方法
        public void hello(string name)
        
{
            txtMsg.Text 
+= string.Format("Hello: {0}\r\n", name);
        }

    }

}


JSDemo.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>Silverlight20</title>
    
<style type="text/css">
        html, body
        
{
            height
: 100%;
            overflow
: auto;
        
}

        body
        
{
            padding
: 0;
            margin
: 0;
        
}

        #silverlightControlHost
        
{
            height
: 100%;
        
}

    
</style>

    
<script type="text/javascript" src="../Silverlight.js"></script>

    
<script type="text/javascript">
        
function silverlightInvokeJS(name) {
            
// Silverlight 调用 JavaScript 方法,在页面上显示结果
            document.getElementById('result').innerHTML += "hello: " + name + "<br />";
        }


        
function jsInvokeSilverlight(name) {
            
// JavaScript 调用 Silverlight 方法,在 Silverlight 上显示结果
            var obj = document.getElementById("xaml1").content.silverlightObject;
            obj.hello(name);
        }

    
</script>

</head>
<body>
    
<div style="font-size: 12px" id="result">
    
</div>
    
<div style="font-size: 12px">
        加载 Silverlight20.WebPage.JSDemo 后,测试 Silverlight 和页面 JavaScript 的交互 
&nbsp;
        
<input type="button" id="btnHello" value="HelloSilverlight" onclick="jsInvokeSilverlight('webabcd')"
            style
="display: none" />
    
</div>
    
<div id="silverlightControlHost">
        
<object id="xaml1" data="data:application/x-silverlight-2," type="application/x-silverlight-2"
            width
="100%" height="100%">
            
<param name="source" value="../ClientBin/Silverlight20.xap" />
            
<param name="EnableHtmlAccess" value="true" />
        
</object>
        
<iframe style='visibility: hidden; height: 0; width: 0; border: 0px'></iframe>
    
</div>
</body>
</html>


OK
[源码下载]