我在aspx页面上有一个Silverlight控件。用户可以选择一个到多个帐户来过滤我在SL控件中显示的一些数据。当他们单击按钮时,会弹出一个“查找”aspx页面,向用户显示帐户列表,并让他们检查他们想要包含的帐户。然后用户单击“插入”,该数据将传递到开始页面上的Silverlight控件。
我遇到了一个仍然困扰着我的问题。帐户查找页面创建一个Account对象数组,然后将其传递给开头页面,如下所示(JavaScript):
var accounts = [{ ID: 1, Name: "Foo"}, { ID: 2, Name: "Bar" }]; // test data
if (window.opener && window.opener.accountsInserted) {
window.opener.accountsInserted(accounts); // pass array of objects to opener
}
在打开弹出窗口(承载Silverlight控件的同一页面)的页面上,我接受该数组,并将其传递给Silverlight对象(JavaScript):
function accountsInserted(accounts) {
silverLightControl.Content.Scriptables.SetAccounts(accounts);
}
尝试调用SetAccounts时,上面的代码会出错。 Silverlight控件中的托管代码执行,但它会抛出异常,例如“无法将ScriptObject转换为Account []” - 这是转换/转换错误。我附加了调试器,并确认它在传递给accounts参数的对象数组反序列化时出现问题。这是运行的托管代码(Silverlight控件中的VB .NET):
<ScriptableType()>
Public Class Scriptables
<ScriptableMember()>
Public Sub SetAccounts(ByVal accounts As ScriptObject)
Dim myAccounts As Account() = accounts.ConvertTo(Of Account())() ' this line throws exception
End Sub
End Class
Public Class Account
Public Property ID As Integer
Public Property Name As String
End Class
顺便说一句,我在Scriptables
的实例中注册为Silverlight控件中的可编写脚本的对象:HtmlPage.RegisterScriptableObject("Scriptables", mScriptables)
现在,在你们开始给我一些尝试的想法之前,我已经开始了。我发现工作在托管Silverlight控件的页面上,我将accounts
数组复制到另一个数组(在托管Silverlight控件的页面上定义),这实际上有效:
function accountsInserted(accounts) {
var newAccounts = [];
if (accounts) {
for (var i = 0; i < accounts.length; i++); {
newAccounts[i] = accounts[i];
}
}
silverLightControl.Content.Scriptables.SetAccounts(newAccounts);
}
这里发生了什么?为什么我必须将数组复制到不同的数组才能使Silverlight控件能够正确地反序列化?