views:

1866

answers:

4

So, I want to create some Silverlight charts from some data on my ASP.NET web page. The way to do this, either using Visifire (my current thing) or the upcoming Silverlight charting, seems to be to create some XAML, or at least some Silverlight objects (like in this Visifire sample), and then stuff them into the page somehow.

Strangely, the only way to do this seems to be through JavaScript! That is, I'd have to do something like this:

User -> click button -> JavaScript event handler -> AJAX call to get XAML from server-sided method -> stuff the XAML-string into the client-sided HTML (like this in general or like this for a Visifire-specific method).

This is highly counterintuitive! What I'd much rather have is the ability to do something like this, inside MyPage.aspx.cs:

protected void MyButton_Click(object sender, EventArgs e)
{
    this.MyFictionalSilverlightControl.Xaml = this.GenerateXamlFromData();
}

That would be much nicer! I'm happy to keep MyFictionalSilverlightControl inside an UpdatePanel, even though it's inefficient; I just wish I knew how to make such a fictional Silverlight control.

Any ideas? Or suggestions on how to do this better?

A: 

I suggest you to download the ASP.NET Silverlight Server Control. More information for this control can be found here. In general, you put the compiled XAM file in the BIN directory and then link the XAML to the asp:Silverlight control. He takes care of the rest. In addition, it is possible to pass some parameters to Silverlight using the input params collection of asp:Silverlight. It is a cumbersome approach, but it works.

Genady Sergeev
I don't see how that would help at all. It still requires a .xap file, which is composed of (among other things) static .xaml and .xaml.cs files; none of these let me set the XAML content from myPage.aspx.cs code-behind.
Domenic
A: 

I could be wrong - coming at this question as a WPF developer rather than a SilverLight developer, but in WPF you can create and insert controls into the XAML in code.

Label myLabel = new Label(); // Create a new control
myLabel.Text = "Hello Wirral"; // Change some of its properties
MyContainingPanel.Children.Add(myLabel); // Add it to an existing container
Sohnee
The problem, I think, is that I don't have any access in e.g. my Page_Load method to any controls like MyContainingPanel (or MyFictionalSilverlightControl).
Domenic
A: 

The really easy solution to this is to just do the table/data presentation in silverlight too. Then use a webservice to provide the data to your silverlight app.

I'm sure MS endorse this wholly.

Otherwise (and you asked for it ;):

The problem with the ideal solution you've provided is that the abstraction of ASP.Net is hiding the reality of double posting for the data as well as building a client interface on the server when the client-side silverlight app can do it perfectly well itself:

Step 1 - Send html to client with data embedded

Step 2 - Initialize a client side application (silverlight app)

Step 3 - Press button calling the GenerateXamlFromData on the server

Step 4 - Get the same data as step 1 and then create some Xaml from it

step 5 - Pass it back to browser

Step 6 - Call a method in the Silverlight application to set the Xaml

Steps 3-5 are totally redundant. On the client you already have the data and something capable of creating charts on the fly, the silverlight app.

If there were an absolute requirement for the table to be in html, the way I would solve it is:

Make your data non-html. Use XML/XSLTransform, JSON/javascript/JQuery, or whatever your favourite client-side transform is to render it. Webservices, whatever. Key thing is here that you open your webpage, http post back for the data and create your html table on the fly. Then pass the same data to you silverlight app and have it create the chart.

Your silverlight application can dynamically build your chart through simple object creation. If you really like poking yourself in the eye with a pencil, you can still dynamically build strings of Xaml and use those to create the chart objects instead, an easy way of earning the StackOverflow badge of Xaml-Nazi

There's still yet another solution to your problem, if you really wanted to you could just pass the Sivlerlight App the html table dom and extract the data from that instead. Generally speaking unless you've done something really stupid html tables conform to XML so just load it into an XDocument.

As for the simple way you describe, afaik it's not possible atm. Maybe one day it will be, but to be honest it will never be a good solution, it will just be a solution for people who want to hack together quick and dirty apps.

mattmanser
I am very confused by this post because I never mentioned an HTML table. What I am actually doing is gathering data from a remote server---that's what this.GenerateXamlFromData() does---and hoping to turn it into a chart. So really it's like 1) send HTML to client with a button saying "get me a chart"; 3) press button; 4) get new data from remote server and create XAML from it; 5, 6) as before.
Domenic
But it sounds like what you are saying is that I need to hack something absurd together like AJAXing the generated XAML into a hidden text field, which some JavaScript then inserts upon AJAX onreadystatechanged into the Silverlight control (since JavaScript is the only way to manipulate Silverlight controls, apparently). The alternative you mention at the beginning is probably best, though. Namely to have the button (which is really a simplification of a whole login/adjust parameters/click button procedure) be all part of a Silverlight XAP instead.
Domenic
+1  A: 

I'd suggest a more AJAXy sort of approach: have JS request the XAML and then runtime insert that XAML into the control (see the HTML Bridge) after the XAML has been returned from the server. That way your control could do a nice animation/transition to the new display.

Still, you can do what you're aiming at:

  • Slap a Silverlight server control into your Update Panel.
  • Write an aspx page to generate the XAML (Change the DocType to make things easier)
  • Point the Silverlight server control at the .ASPX page:

    ... asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/myXAMLPage.aspx" MinimumVersion="2.0.30523" Width="100%" Height="100%">

  • Trigger the UpdatePanel to do it's thing whenever a user clicks your button.

Now, whenever a user clicks a button, the Update Panel (containing the Silverlight control) will be rendered, and that SL control will request the XAML file and render what it finds.

Do note, this approach instantiates the control with a XAML file. This means that you won't be able to use managed code in Silverlight. If you need managed code, instead of specifying the "myXAMLPage.aspx" page in the Source, specify your .xap file and then use an initparam to specify "myXAMLPage.aspx". Inside you're Silverlight application, download the xaml file (WebClient or whatever), and then use XamlReader.Load to load it up and display it.

hth, Erik

Erik Mork
That's _perfect_. Thank you so much. Exactly what I was looking for.
Domenic
wahoo. Thanks!
Erik Mork