做實驗驗證了Silverlight傳送Dictionary<string, string>到Javascript端的行為。

依據MSDN文件的說法:

By default, properties and return values typed as IDictionary are returned by reference, using a JavaScript wrapper that is similar to a dictionary.

Javascript Dictionary Wrapper提供obj[key]、obj.key的存取方式,並可新增key/value,但不支援for (var p in obj)的Javascript Key列舉。如果想要支援Key列舉及其他功能,還是得回歸Javascript Object。

以下程式示範傳回Dictionary<string, string>及將其轉為Javascript Object的兩種做法:

public Page()
{
    InitializeComponent();
    if (HtmlPage.IsEnabled)
    {
        HtmlPage.RegisterScriptableObject("JSIO", this);
    }
}
[ScriptableMember]
public Dictionary<string, string> GetDictionary()
{
    Dictionary<string, string> dict = new Dictionary<string, string>();
    dict.Add("A", "公理號");
    dict.Add("B", "大買家");
    //會傳回被Javascript Dictionary Wrapper包裝的Managed Object到Javscript端
    return dict;
}
[ScriptableMember]
public ScriptObject GetJSDictionary()
{
    //將Dictionary<string, string>轉成標準Javascript Object
    Dictionary<string, string> dct = GetDictionary();
    ScriptObject jsDct = HtmlPage.Window.Eval("new Object()") as ScriptObject;
    foreach (string k in dct.Keys)
        jsDct.SetProperty(k, dct[k]);
    return jsDct;
}

前端測試時,for (var p in d1)迴圈執行次數為零,但可以使用d1.A或d1["B"]存取Dictionary內的儲存值;包裝為Javascript Object後,使用起來就如同一般物件,支援for (var p in d2)。

    function onSilverlightLoad(sender, args) {
        var slCtl = sender.getHost();
        var jsio = slCtl.Content.JSIO;
        var d1 = jsio.GetDictionary();
        for (var p in d1)
            alert("d1.Foreach: " + p);
        alert("d1.A=" + d1.A); alert("d1.B=" + d1["B"]);
        var d2 = jsio.GetJSDictionary();
        for (var p in d2)
            alert("d2.Foreach: " + p + "->" + d2[p]);
    }

Comments

Be the first to post a comment

Post a comment