Lessons from the Trenches: Visual Studio 2008 and Silverlight 1.1

I’ve been heads-down in Visual Studio 2008 Beta 2 and the Silverlight 1.1 Alpha Refresh for the past several days. Now that I’ve come up for air, I’d like to share a few tips, tricks, and work-arounds for glitches in the current builds that other developers might find helpful.

SILVERLIGHT.JS
After you install the July 2007 Microsoft Silverlight Tools Alpha Refresh for Visual Studio, you can create Silverlight 1.1 projects in Visual Studio. However, the copy of Silverlight.js that Visual Studio includes in new projects goes with Silverlight 1.0, not 1.1. The result? If someone visits your Silverlight 1.1 page and they don’t already have Silverlight 1.1 installed, they’re prompted to install the wrong one. Then they’re prompted again, and again, and again…

The fix is to replace the version 1.0 Silverlight.js file Visual Studio added to your project with version 1.1. You can grab the correct version from the SilverLife source code.

XAML PARSER DOESN’T HANDLE CUSTOM CONTROLS CORRECTLY
Custom controls derive from System.Windows.Controls.Control, and from it they inherit certain properties such as Width and Height. You typically reimplement these properties in derived classes and hide them by tagging them with C#’s new keyword. However, these properties can’t be initialized declaratively because the XAML parser doesn’t properly generate calls to the property setters. Instead of doing this:

<custom:MyControl x_Name=”MyControl1″ Width=”200″ Height=”200″ … />

You have to do this:

<!– XAML –>
<custom:MyControl x_Name=”MyControl1″ … />

// C#
MyControl1.Width = 200;
MyControl1.Height = 100;

Interestingly, other properties–that is, ones that don’t come from the base class–can be declaratively initialized just fine.

GETTING RID OF TESTPAGE.HTML
Visual Studio includes files named TestPage.html and TestPage.html.js in every Silverlight 1.1 project. You can change TestPage.html’s name in Solution Explorer, but you can’t rename TestPage.html.js. (And if you do it manually, the link between the two files in Solution Explorer is lost.)

As a work-around, go out to the file system and rename the files. In SilverLife, for example, I named them Default.html and Default.html.js. Then open the SLN file in Notepad and change this:

<ItemGroup>
<None Include=”TestPage.html” />
<None Include=”TestPage.html.js”>
<DependentUpon>TestPage.html</DependentUpon>
</None>
</ItemGroup>

to this:

<ItemGroup>
<None Include=”Default.html” />
<None Include=”Default.html.js”>
<DependentUpon>Default.html</DependentUpon>
</None>
</ItemGroup>

Reopen the project in Visual Studio and the files will appear in Solution Explorer properly linked together.

STORYBOARDS AS GAME TIMERS
In SilverLife, I needed a timer to drive automated simulations. HtmlTimer is deprecated and not very reliable. System.Threading.Timer wasn’t an option because at present, there’s no way to marshal timer callbacks back onto the UI thread. So I declared a Storyboard in XAML and wired a handler to its Completed events for use as a timer:

<!– XAML –>
<Canvas.Resources>
<Storyboard x_Name=”Timer” />
</Canvas.Resources>

// C#
Timer.Completed += new EventHandler(OnTick);

It worked fine initially but proved totally unreliable. Simply running the project from a directory other than the one in which it was created caused Completed events to stop firing (or the handler to never be called).

I found a work-around after 10 hours of head-banging: wire the event to the event handler declaratively:

<Canvas.Resources>
<Storyboard x_Name=”Timer” Completed=”OnTick” />
</Canvas.Resources>

So far it’s working just fine, and it works in Firefox, too.

As an aside, despite documentation and blog posts to the contrary, I found that it’s not necessary to declare a target for Storyboard objects in the Silverlight 1.1 Alpha Refresh. Maybe it’s just me…

HTML BRIDGE / DOM INTEGRATION
To close on a positive note, I found that the DOM integration features not only work well, they’re downright amazing. How cool is it to be able to call into managed code from JavaScript and even process managed events in JavaScript? I found a handy use for the latter.

I’d like to be able to execute the equivalent of window.alert from managed code, but the Alpha Refresh doesn’t support that. What you can do instead is declare a scriptable event in your XAML code-behind class:

[Scriptable]
public partial class Page : Canvas
{
public void Page_Loaded(object o, EventArgs e)
{
InitializeComponent();
WebApplication.Current.RegisterScriptableObject(“magic”, this);
}

    [Scriptable]
public event EventHandler<ShowMessageEventArgs> ShowMessage;

}

Then register a JavaScript handler for the event like this:

var control = document.getElementById(‘SilverlightControl’);
control.content.magic.ShowMessage = onShowMessage;

Finally, call window.alert in the handler, like this:

function onShowMessage(sender, args)
{
window.alert(args.Message);
}

Now, anytime you want to pop up an alert box, simply fire a ShowMessage event from managed code:

ShowMessage(this, new ShowMessageEventArgs(“Hello, world!”));

I derived ShowMessageEventArgs from EventArgs and marked it scriptable. I also built in a Message property and marked it scriptable, too. That way I can pass the message that I want to appear in the alert box in ShowMessageEventArgs.Message and easily access it in the JavaScript handler.

 

Jeff Prosise

View Comments

  • Silverlight has an interesting clause in the license:
    You may not ...
    work around any technical limitations in the software
    I wonder if all your work-arounds presented on this page qualify as violations :)
    OK, it's a joke, but the clause _is_ silly, and technically you may be violating it (although this clause is most likely not enforceable in US).

  • Jeff,
    I don't know how you do it. This is exactly the type of exploration I want to be doing, but the demands of work/family/body don't leave me time.
    Thanks for doing the work for me!
    ++Alan

  • Hello.
    regarding the targetname/targetproperty properties, i belive that they're necessary if you add animations to your storyboard (at least, that was my experience with them)

  • Very cool stuff... My takes on a couple of the items:
    - Timer...hopefully in the next couple months we will get one in a 1.1 beta. The workaround is great if u want to get a more detailed timer (i.e. for games), but for now I am sticking with the HtmlTimer...since its going to be a code change when the new one comes out anyway :)
    - JavaScript/Event Handling is a beauty like u said. For a more detailed look (for everyone else) check out the QuickStart:
    http://silverlight.net/QuickStarts/Dom/ManagedCodeAccess.aspx
    Some of the items I have found:
    - integration between: AJAX, ASP.NET 3.5 and Silverlight 1.1 is excellent. It removes some of the "big" roadblocks stopping most developers from playing with it (i.e. no basic controls). Need a nice looking Grid integrated into Silverlight? No Problem.
    - Another tip for integrating AJAX and Silverlight is to NOT use the ASP.NET Futures Silverlight Control that allows u to integrate Silverlight/ASP.NET together. Use the JavaScript CreateSilverlight command manually..u have more options!
    - Always check the boards for updates!! That sounds like common sense, but in the last 4 months we have had about 8 (or so) releases to: Silverlight 1.0, Silverlight 1.1, Expression Blend 2, Design, Media Encoder, VS 2008 tools and SDK etc. It is real easy to get lost and WASTE a bunch of time when not having the proper toolset. I check for new Silverlight stuff almost everyday :)

  • Time for another weekly round-up of developer news that focuses on .NET, agile and general development

  • I have VS 2008 beta 2, Microsoft Silverlight Tools Alpha for Visual Studio 2008 Beta 2
    when I put in this:
    WebApplication.Current.RegisterScriptableObject("magic", this);
    got error at compile:
    Error 7 'System.Windows.WebApplication' does not contain a definition for 'RegisterScriptableObject' and no extension method 'RegisterScriptableObject' accepting a first argument of type 'System.Windows.WebApplication' could be found (are you missing a using directive or an assembly reference?) C:devAOLwebMailProControlTestControlTestControlTestPage.xaml.cs 44 36 ControlTest
    naything else I need to do for making it work? Thanks!

Recent Posts

8-Step AWS to Microsoft Azure Migration Strategy

Microsoft Azure and Amazon Web Services (AWS) are two of the most popular cloud platforms.…

2 weeks ago

How to Navigate Azure Governance

 Cloud management is difficult to do manually, especially if you work with multiple cloud…

3 weeks ago

Why Azure’s Scalability is Your Key to Business Growth & Efficiency

Azure’s scalable infrastructure is often cited as one of the primary reasons why it's the…

1 month ago

Unlocking the Power of AI in your Software Development Life Cycle (SDLC)

https://www.youtube.com/watch?v=wDzCN0d8SeA Watch our "Unlocking the Power of AI in your Software Development Life Cycle (SDLC)"…

2 months ago

The Role of FinOps in Accelerating Business Innovation

FinOps is a strategic approach to managing cloud costs. It combines financial management best practices…

2 months ago

Azure Kubernetes Security Best Practices

Using Kubernetes with Azure combines the power of Kubernetes container orchestration and the cloud capabilities…

2 months ago