2

Suppose I have a class in SilverLight:

public class GenericClass {

    public string filedOne = "field one";

    public string filedTwo = "field two";

}

And I want to pass an instance of it to JavaScript to access in the following way:

function callback(obj) {
    console.log(obj.fieldOne);
}

Is this possible without serializing to JSON and back?

UPDATE:

I know how to pass primitive values - that's not a problem. I need to pass an object with several fields.

jayarjo
  • 16,124
  • 24
  • 94
  • 138
  • By definition, if you're passing it from SL to JS you *are* serializing it..... – Jamiec Aug 24 '12 at 13:55
  • I mean I do not want to do any serialize/unserialize operations myself, if silverlight-to-js bridge does it behind the curtains it's ok. So... any idea how I can achieve this, or if it's possible at all? – jayarjo Aug 24 '12 at 14:00

2 Answers2

3
public partial class TestPage: UserControl
{
    public TestPage()
    {
        InitializeComponent(); 
        MyClass myObject = new MyClass();
        myObject.SomeMember = "TEST";
        HtmlPage.Window.Invoke("JSFunction", myObject);
    }        
}

UPDATE: In order to pass non-primitive type objects to javascript; the class definition shall be marked with ScriptableType attribute. All properties of this class shall also be marked with ScriptableMember attribute.

[ScriptableType]
public class MyClass
{
    [ScriptableMember]
    public string SomeMember { get; set; }    
}
daryal
  • 14,643
  • 4
  • 38
  • 54
  • I can pass primitive variable, that's not a problem. I need to pass an object, just as I described. – jayarjo Aug 24 '12 at 14:25
3

Use the ScriptableTypeAttribute

[ScriptableType]                       
public class SMT_ScriptableManagedType
    {
    [ScriptableMember(EnableCreateableTypes = false)] // No access
     public string GetString1()
        { return "abcdefg"; }

     public string GetString2()            // Can be accessed.
        { return "123456"; }
}

Now you can pass the object like this:

HtmlPage.Window.Invoke("ReceiveSMT", new SMT_ScriptableManagedType());

Where ReceiveSMT is a javascript function which will receive the object as a parameter.

Emond
  • 50,210
  • 11
  • 84
  • 115
  • And how do I access the members of that object? It is a bit different pattern anyway. Is it impossible to keep it the way I described above? – jayarjo Aug 24 '12 at 14:29
  • just use them. there is nothing special about those. – Emond Aug 24 '12 at 18:18
  • I need it differently. Actually I found that I can mark class field as [ScriptableMember] too and then instance is in fact passed to JavaScript callback. The problem is that the resulting object is not enumerable, therefore I can't do anything to it, unless I'm aware of it's structure. And I'm not. Do you know howto make it enumerable? – jayarjo Aug 24 '12 at 18:27
  • 1
    See http://stackoverflow.com/questions/8024149/is-it-possible-to-get-the-non-enumerable-inherited-property-names-of-an-object to get the non-enumerable properties. – Emond Aug 24 '12 at 18:35
  • Awesome! Although not supported in IE8 and less (http://kangax.github.com/es5-compat-table/), which makes it useless for me :| – jayarjo Aug 24 '12 at 19:10