ScriptObject提供了GetProperty, SetProperty可以讀取及修改屬性,但是獨缺for (var p in obj)的做法一口氣列出Javascript物件所有的屬性及方法。

原本有個構想,Sivlerlight Method在承接Javascript傳來參數時,想學習jQuery利用object傳遞即興組合參數設定的寫法,例如:

$("#dvX").css({ position:"absolute", left:"2px", top:"100px", width:"200px" });

只是,即便Silverlight端用ScriptObject接下傳入的參數,若無法透過列舉方法找出其中有哪些屬性,一樣無法發揮Javascript端的隨性與彈性。

先前jssk_IsFunction的做法給了啟示示,Javascript擅長的事還是可以交給Javascript來做,這才符合"閃開! 讓專業的來"之終極奧義:

        public string[] GetProperties(ScriptObject obj)
        {
            string script = @"
if (window.jssk_ListProperties == undefined) 
    window.jssk_ListProperties = function(obj) {
        var a = [];
        for (var p in obj) 
            if (typeof(obj[p]) != 'function')
                a.push(p);
        return a;
    }
";
            HtmlPage.Window.Eval(script);
            return ((ScriptObject)HtmlPage.Window.Invoke(
                "jssk_ListProperties", obj))
                .ConvertTo<string[]>();
        }

很簡單吧!


Comments

# by Asimo

您好,不好意思請教個問題 當執行到HtmlPage.Window.Eval(script);該行, 我會出現 "這項作業只能發生在 UI 執行緒上" 錯誤訊息, 因為我是想將script裡的內容 直接丟到html上給JavaScript去處理, 沒有任何silverlight的UI去接, 請問一下我該怎麼解決?!感恩

# by Asimo

您好,不好意思請教個問題 當執行到HtmlPage.Window.Eval(script);該行, 我會出現 "這項作業只能發生在 UI 執行緒上" 錯誤訊息, 因為我是想將script裡的內容 直接丟到html上給JavaScript去處理, 沒有任何silverlight的UI去接, 請問一下我該怎麼解決?!感恩

# by Jeffrey

to Asimo, 你的HtmlPage.Window.Eval是否以其他執行緒執行? 若是,可參考http://bit.ly/c9ZhFu ,用Dispatcher.BeginInvoke技巧克服。(HtmlPage.Window.Dispatcher.BeginInvoke)

# by Asimo

嗯 是在其他執行緒執行 也試了一下您提供的方法, HtmlPage.Window.Dispatcher.BeginInvoke(() => HtmlPage.Window.Eval(script)); 一樣會出現"這項作業只能發生在 UI 執行緒上" 錯誤訊息, 應該是判斷到HtmlPage.Window.Eval就會跳出訊息, 還是說Dispatcher.BeginInvoke的另一個執行緒也不是UI執行緒?,

# by Jeffrey

to Asimo, 先前HtmlPage.Window寫法有誤,請參考以下範例: (用UserControl.Dispatcher.BeginInvoke()) public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); if (HtmlPage.IsEnabled) { HtmlPage.RegisterScriptableObject( "JavascriptSidekick", this); } } [ScriptableMember] public void ThreadTest() { ThreadPool.QueueUserWorkItem((o) => { Dispatcher.BeginInvoke(() => { HtmlPage.Window.Eval("alert('YES');"); }); }); } }

Post a comment