I’m ready to begin my first production Silverlight 2 project, so I needed to learn how to make a data driven Silverlight application. I pretty much already knew that the answer would involve WCF, but as I do not have much experience with such things I was not sure what to expect. I had written several Web Services in PHP using NuSOAP, but I knew basically nothing about WCF or IIS hosting of web services. So, towards the goal of understanding what all the pieces are and how they fit together, I began my research.
Getting Started with WCF
As an old procedural midrange programmer, I always like to start with the data, so the WCF end was where I chose to begin. I tried watching Michele Bustamante’s 15 part video series on WCF, but half way through the second video my eyes glazed over and the drool was beginning to stain my shirt. While I understand she is a giant in the field, this series was not for the rank amateur.
I surfed around Google for a while and came up with several decent examples and a couple of videos. At some point, once I understood the basics, I stumbled across an example of the new Silverlight-enabled WCF Service item type which greatly simplified things. I hooked up a Linq to SQL project to my WCF service and was able to return Linq classes (or subsets as necessary).
I was able to hook up a simple WCF test inside a Silverlight 2 application and consume my new Services. All was well, but I had done everything inside the Silverlight project. It made more sense to me to break the WCF out into its own Solution. To accomplish this, I followed these steps:
- Create a WCF Service Application
- Delete the default Service1 files
- Add a new “Silverlight-enabled WCF Service” item
- Create the services as needed
Deploying the Service to IIS 6.0
I’m unfortunately still stuck with IIS 6.0. I don’t know if the experience is any different on IIS 7.0, but I went through some trials getting this to work properly. To be fair, I’m sure that most of the trials were caused by my own ignorance.
At first, I was trying to deploy the Services as part of an existing ASP.NET application. This got hairy pretty quickly, since I wasn’t sure how to properly merge the two projects together on the server. I tried deploying the Services to a subdirectory, but I could never get it to work. At that point I decided that it would probably be best if I put the services on their own subdomain, so I created a new subdomain for the Services.
I was able to deploy the Service site to the new subdomain and the WSDL page displayed properly. (Actually, it didn’t right away: I had apparently screwed something up trying to merge it with the other ASP.NET application, so I recreated the Service application from scratch which only took a few minutes. It was that page that displayed properly.)
So at this point I thought I should have been able to simply switch out my Service Reference in my Silverlight application, but it didn’t work. I messed around with it but couldn’t get it to respond. When I ran the application in debug, I received a message indicating that the WCF Service was not configured for cross domain access. Since the Service was now live on the domain but my application was running on localhost, my requests were being rejected by the server. To solve this, I added a clientaccesspolicy.xml file. At this point, the test Silverlight application running on my local machine began functioning again.
Deploying the Silverlight Application
Now, with my Service installed, configured, and running as desired, and with my Silverlight 2 application consuming that Service, I figured I was ready to deploy it to the server. I created my new ASP.NET web site on IIS 6.0 and deployed the Silverlight application’s test ASP.NET page. I pointed my browser to the test page and… nothing.
And by nothing, I mean I received the dreaded blank page. Even worse, when I tried to right-click to view the source, all I got was the “Silverlight Configuration” prompt. At first I was really bummed, but then I realized that if I was getting the Silverlight prompt, then that meant the browser recognized my content as Silverlight! I was actually closer to success than I originally imagined!
Once more unto the Google breach, and I found that, at least in IIS 6.0, you have to configure a MIME type for .xap files! I navigated to the MIME settings on my Silverlight domain and added a Type for extension “.xap” with a content type of “application/x-silverlight-app”. I restarted the web site and went to my page and Viola! I had a Silverlight 2 application running on IIS 6.0 that consumed WCF Services!
So now that I have the basic structure down, I have a bit of work left to do. First, I need to test all my Services. Then I need to read up on performance for WCF: I believe there are some lazy loading techniques I can use to make sure my users are getting immediate access and not waiting around for a bunch of data to load. After that, it will be back to Blend 2 for some serious design work. I don’t have anything particularly juicy in mind for this application, but I do want something a little beyond the ordinary. Along the way, I’m hoping to upgrade to Server 2008, Sql Server 2008, and IIS 7.0. And in January I am taking Computer Graphics classes at the local community college. All in all, it looks like I’m going to be having a lot of fun in the near future!
OK, I know, absolutely nothing to do with .NET, but I’m sure my fellow Trekkers out there will appreciate this. There is an awesome new trailer on http://www.startrekmovie.com/ for the next Star Trek installment. And I must say I am very impressed!
And, the site itself is very impressive. It is a Flash 10 site that has some great effects. I used to see a site like this and believe that it was out of my reach as a developer, after all I’m no graphic artist. But these days, when I see something like this I start to think that I could get results like this in Silverlight. Personally, I’m starting to get very excited about web development again.
Last night at RVNUG, a friend of mine pointed me to The WPF Toolkit. The toolkit is a collection of controls and features that extend the current WPF offering from Microsoft. Chief among these is the DataGrid control, but something more appealing caught my eye: Visual State Manager.
Basically, the VSM is a very easy to use feature of Blend 2 SP1 that supports Silverlight 2. It allows the developer to easily set the visual state of user controls and control templates based on the current state of the control, such as MouseOver and Pressed. I had seen this when I was exploring Silverlight 2 in Blend 2, but I’ve been focusing on WPF and was curious as to why I didn’t have the same functionality I had seen in Silverlight. Of course, now I know: VSM is currently only included as part of Blend 2 for Silverlight 2 development. But, if you install the WPF Toolkit and follow the instructions in the link above to update your Registry, you can gain access to the same basic functionality for WPF Applications.
Using VSM in WPF
Previously, these state changes could be accomplished using Storyboards and Timelines, and then assigning their beginning and ending to Triggers. The Timeline tool in Blend is robust and feature rich, but I think for a non-graphically oriented developer it can be more than a little daunting. And it seems to be overkill for simple animations. That’s where VSM comes in: it greatly simplifies the task of adding small animations to element states.
The Silverlight implementation is very nice and intuitive right out of the box: the states are already defined and all you have to do is activate one and make your changes to the art board. Unfortunately, the current version for WPF is not as straightforward. In WPF, once you have the State manager visible, you have to create the State Groups and define the Visual States you wish to modify. Once I figured out what was going on, this is not painful by any means, but it took some trial and error to get it working right. Don’t forget to add a reference to %Program Files%\WPF\WPF Toolkit\…\WPFToolkit.dll to each project in which you wish to use VSM. Trust me, it will save you a lot of heartache!
So first things first, we need something that VSM can interact with. Since VSM cannot be applied to the default template of a control, we need to create our own. For this article, I created a button and then created an empty template. Once you create the template, either by ‘edit a copy’ or ‘create empty’, the States Manager will appear under the Triggers Manager on the left hand pane. At this point, the only item visible in the States Manager is Base. You can go ahead and create the default look of your template at this point.
Set up the State Manager pane
To begin with we need a Visual State Group to hold our Visual States. In the Top Border of the States Manager pane on the far right side is a small icon with a plus sign on it. Hovering over it will reveal that this is the “Add state group tool. Pushing it will create a new Visual State Group header under Base. Click on the title (VisualStateGroup) and rename it as you see fit. I’m not sure that the group names matter, but to be on the safe side I followed the same scheme that Silverlight reveals and called my first one “CommonStates”.
Now that we have a group to hold our collection of Visual States, we can start adding states. On the CommonStates header bar is another icon with a plus symbol: this is the “Add state” button, so press it to add a new state. Rename VisualState to the desired state. The state names do matter if we are to get the desired result, so I added three typical states: Normal, MouseOver, and Pressed.
Now that we have all the missing pieces defined, we can use them just as we do in Silverlight 2. Clicking on the desired state in the State Manager pane will turn on State Recording [as indicated by the red border around the art board and the header message "State recording is on"]. Now you can easily adjust the display elements of the content to whatever you want them to be at that particular state. A classic example would be brightening a button on MouseOver.
When you are done editing the visual elements, click on Base in the State Manager pane to exit state recording mode. It is important that you do this, because otherwise you could easily alter just a given state when you think you are altering the control template itself. Take it from me, this is very frustrating when you do not receive the results you expect. And then, of course, to correct it you need to back all of your changes out and reapply them outside of state recording mode.
If you have done all of the above, your button should be changing its visual appearance when you mouse over or press the button. You may think this is the end, but wait, there’s more! Leaving it as above will force the change from one state to another to happen immediately. While we have become accustomed to such UI, it is not the most pleasing effect. Instead, users react much better to very slight, more realistic animations. In other words our users will find our software more appealing if it takes a little time to change from one state to another. These quick, smooth changes from one state to another are very short and simple animations called “Transitions”.
To add a Transition, find the Visual State (such as “MouseOver”) in the State Manager pane and look to the right side of the header bar. There you will find an arrow icon adorned with a plus symbol (notice a pattern developing here?) Click on that and a helper window will appear with a collection of Transitions you can modify. In my case, I chose the two with the ‘*’. The one with the * on the left side indicates the transition from any other state to the selected state, and the one with the * on the right indicates the transition from the selected state to any other state.
Clicking on the desired Transition will add it beneath the selected state. On the Transition you will find a text box that lets you enter the desired amount of time you wish the particular Transition to take. The available range is 0 to 1 second. It doesn’t take much for our Transition to have the desired effect, so try .1 or .2s at first to get the feel for it, then adjust as you desire.
Now when you run your project, you should detect the pleasing effects of Transitions. Overall, I find this much much easier than Storyboards and traditional animations. I’m sure that eventually the tooling for WPF Applications will improve to match what is in Silverlight, but overall it is a minor complaint. I want to thank the CodePlex guys for letting us in on this great secret!