views:

26

answers:

2

Curious how this could be done. Is there any way to create a delegate method within a Silverlight control that can be used within an Asp.net page that the control resides?

For example, let's say you are creating a Silverlight control that solicits information from a user (Ie. Name, age, etc), is there a way to somehow bind to a click event on the Silverlight control from the asp.net page it is sitting on, and then get the information from that Silverlight control?

+1  A: 

It is possible to do what you ask, but it doesn't have much to do with ASP.Net. Since Silverlight runs on the client you would just have the click event in Silverlight update the html content. You could then send that data back to the ASP.Net when you do a postback.

Unless you have a good reason to do this, it probably isn't the best approach. You'd probably be better of sending the data back to the webserver using a web service instead of going through ASP.Net.

Bryant
Good point(s). I was just thinking if my control were to be "re-usable" in the future by pages it sits on, but now that I think about it, the only way to trigger something on the asp.net page would be HTML updates or Javascript triggering.Best leave the control as a stand-alone.
Mark Kadlec
+1  A: 

I done that registering a Javascript event and manually calling back my server controls. Some important pieces below:

<asp:Silverlight runat="server" ID="SilverlightUpload" 
     Source="~/ClientBin/Silverlight.xap" OnPluginLoaded="pluginLoaded" />
<asp:Button runat="server" OnClientClick="return cancelUpload()" Text="Cancel" />

<script type="text/javascript">

    var uploadControl = null;
    function pluginLoaded(sender) {
        uploadControl = sender.get_element().content.uploadControl;
        uploadControl.addEventListener("OnFileListChanged", onFileListChanged);
    }

    function onFileListChanged(sender, e) {
        var files = [];
        for (var i = 0; i < e.Files.length; i++) {
            files[i] = {
                Id     : e.Files[i].Id, 
                Name   : e.Files[i].Name
            };
        }
        __doPostBack("<%= RadGrid1.UniqueID %>",
                     "OnFileListChanged:" + JSON.stringify(files));
    }

    function cancelUpload() {
        $find("<%= SilverlightUpload.ClientID %>")
             .get_element().content.uploadControl.StopUpload();
        return false;
    }

</script>

And Silverlight codebehind:

[ScriptableType] // MUST
public partial class Page : UserControl
{
    [ScriptableMember] // MUST
    public event EventHandler<FileListChangedEventArgs> OnFileListChanged;

    [ScriptableMember] // MUST
    public void StopUpload() { }
}

[ScriptableType]
public class FileListChangedEventArgs : EventArgs
{
    public FileUploadItem[] Files { get; internal set; }
}

[DataContract]
[ScriptableType]
public class FileUploadItem
{
}
Rubens Farias
Very cool, I'm going to try this.
Mark Kadlec