With the VS2008 and .NET Framework 3.5 Service Pack 1 Beta released Scott Guthrie has posted a very detailed article on the new features and changes that this service pack introduces. Unfortunately, this beta release is incompatible with the current Silverlight tools beta. However, ScottGu hints that a new version of the Silverlight tools will become available in the next few weeks.
I'll be speaking at PDANUG on May 13th, 2008 on creating Templatable Silverlight Controls. Go register now!
Creating reusable controls is an important aspect of productive software development. When you can supplement this reusability with customizability, you have the power to rapidly deliver seamless and compelling user experiences in your products. Silverlight offers both of these through the use of custom templatable controls. In this presentation, we will take a short journey through the process of building a custom control using Silverlight.
See you there!
The development experience in Visual Studio 2008 beats the experience in any previous release hands-down. However, the addition of JavaScript debugging has caused me a slight issue. While debugging solutions that contain JavaScript, you may have noticed that a additional tree node that pops up in the Solution Explorer called Script Documents. This node represents all of the current JavaScript sources for the current request.
This is a great feature, but if you have lots of JavaScript, it can really damage your productivity, especially if you aren't working on the JavaScript code at the moment. You see, if you use components that are heavy in JavaScript like he ASP.NET components from DevExpress, Visual Studio spends a good deal of time, unloading the Script Documents from the current page and loading the Script Documents for the next page. It really doesn't take long to get fed up and start looking for an answer.
So, after a little research, I found that the Script Documents node only appears when you have Script Debugging Enabled. You can toggle these settings in your Internet Explorer settings:
So here are the issues that I have set out to solve:
- The productivity loss from waiting on the Script Documents node to load up is substantial.
- I couldn't find a way to disable the Script Documents node from inside of Visual Studio (although there may be a hidden registry setting for doing so).
- It's fairly annoying to have to toggle these settings in Internet Explorer each time you wish to hide the Script Documents node.
Toggle Script Debugging Addin for Visual Studio 2008
I've built an addin for Visual Studio 2008 that will allow you to quickly toggle JavaScript debugging from inside of Visual Studio. When you don't need to debug JavaScript files, simply click on the addin icon and Script debugging will be disabled. When you need Script debugging again, simply enable Script Debugging by clicking the addin icon once more:
That's really all there is to it. The project is hosted on CodePlex so go download it and give it a shot! Enjoy!
Download the Add-in Here
Version: 1.0.0
Date Published: 4/24/2008
Requirements: Visual Studio 2008
A question was recently asked in the forums about logging client-side Silverlight exceptions on the server-side? Of course, my first guess would be to create code that would trap exceptions and call out to a web service for logging purposes. But why do that when someone has already done all the work for you? Daniel Vaughan has developed Clog (Client Logging) a customizable logging system for Silverlight. You can read all of the details about Clog in his article on CodeProject. Enjoy!
For those of you that follow my blog and care enough to follow me on Twitter, my user name is pbrooks. I've been trying my best to post at regular intervals. See you on Twitter!
There seem to be a lot of strong opinions about the absence of Synchronous Web Service calls in the Beta 1 release of Silverlight 2, so I thought I would try and condense the points brought forward by the two opposing forces into an easily digestible format.
Camp 1: Synchronous Web Service calls are missing and rightly so!
- Synchronous calls will block the web browser's UI thread, rendering the browser unresponsive.
- Microsoft did this to prevent developers from....<<insert self-mutilation saying here>>.
- Microsoft did this to protect Silverlight platform from getting a bad rap.
- Microsoft did this because of cross-platform limitations.
- Flash Web Service calls are asynchronous.
- Synchronous calls are dangerous because you are depending on receiving a response that might not happen.
- Synchronous calls are easier to make and therefore easier to abuse.
Camp 2: Synchronous Web Service calls are missing and you have ruined my life!
- Asynchronous calls are causing my code to be difficult to read and maintain.
- If I want to ....<<insert self-mutilation saying here> then I should be able to do it.
- Most web service calls are short-lived and aren't transferring gobs of information.
- At least support background threads and let us call synchronously there.
- At least provide a way to simulate synchronous behavior.
Hopefully, Microsoft will come up with a good compromise to satisfy both camps!
It's 4:30am and I'm on my way to the Heroes Happen Here event in Charlotte, NC. Normally PDANUG is held on the 2nd Tuesday but with the scheduling conflict, we have moved the April PDANUG event to Tuesday, April 29th, 2008. Chris Reeder will kick of the event with a presentation on a few new SQL Server 2008 features, Chris Craft will follow with an introduction to a few IIS7 features, and I will be presenting on the new features of Visual Studio 2008. It should be a great event. Please be sure to register from the site so we know how much food to order.
In Silverlight, it seems that most of the time, you need to reach into the hosting page from the managed world, but what if you want to reach into the managed world from the hosting page? In other words, what if you want to subscribe to a managed event from JavaScript?
Let's look at an example. Suppose we have a button in our Silverlight application for which we want our web page to respond.
XAML:
1: <Button x:Name="Button1" Height="35" Width="120" Content="Do Something" Click="Button1_Click" />
C#
...
1: public partial class Page : UserControl
2: {
3: [ScriptableMember]
4: public event EventHandler ButtonClicked;
5:
6: public Page()
7: {
8: InitializeComponent();
9: HtmlPage.RegisterScriptableObject("ScriptablePageObject", this);
10: }
11:
12: private void Button1_Click(object sender, RoutedEventArgs e)
13: {
14: if (ButtonClicked != null)
15: {
16: ButtonClicked(sender, e);
17: }
18: }
19: }
...
Pay special attention to the ScriptableMember attribute that has been applied to the ButtonClicked event. This causes Silverlight to expose the the type to the hosting page. The RegisterScriptableObject call tells Silverlight to expose the containing type using the alias 'ScriptablePageObject'.
Now, we just need to subscribe to the exposed event on the JavaScript side:
...
1: <asp:Silverlight
2: ID="Xaml1"
3: runat="server"
4: Source="~/ClientBin/CallHtmlDom.xap"
5: OnPluginLoaded="pluginLoaded"
6: Version="2.0"
7: Width="100%" Height="100%" />
8: </div>
9: </form>
10: <script type="text/javascript">
11:
12: function pluginLoaded(sender,args) {
13: var slCtl = document.getElementById("Xaml1");
14: slCtl.Content.ScriptablePageObject.addEventListener("ButtonClicked", jsEventHandler);
15: }
16:
17: function jsEventHandler(sender, args) {
18: alert("Button Clicked");
19: }
20:
21: </script>
Once the Silverlight plugin has loaded, pluginLoaded is called which, in turn, registers the JavaScript event handler. Enjoy!
The question of calling JavaScript functions from Silverlight seems to come up quite often and there are solutions to the problem. But one answer I have not seen yet is to use the HtmlPage.Window.Eval method. This method is simply a pass-through to the Eval method in JavaScript on the browser end. It might not be an appropriate solution in all cases, but it's always nice to have options!
1: // C# Code
2: HtmlPage.Window.Eval(string.Format("doSomething('{0}');", "hello there!"));
1: // JavaScript Code
2: function doSomething(message) {
3: alert(message);
4: }