Latest Tweet:
  • Loading...

Earlier today I gave my “Silverlight 2 for Developers” talk at TechEd New Zealand. I know the title is a little bit vague, but the session was generally trying to give developers who want to build “real applications” a good starting point. It’s a level 300 talk (advanced), so it skips the basic introduction. That being said you don’t need to be a Silverlight expert to find the session useful. The talk covered things like CRUD applications using WCF, how to implement a Presentation Model/ViewModel, how to use IoC and DI in Silverlight, and how to do unit testing in Silverlight.

 Presenting at TechEd

The theme of the talk was diving, and for the demos I worked on a dive log application. The application is fairly complete, and I’ve made it available online for anyone to play with. The code should also be a good sample application for anyone who wants to get into building data centric Silverlight applications. I’m planning on building on the dive log sample in future blog posts, and already have several ideas in the pipeline.

You can run the application by clicking the screenshot. You will be asked to login, and any username and password will be valid. If the user doesn’t exist it will be created when you login. You can even run the unit tests directly from your browser if you want.

Dive Log Screenshot

Slides

I've uploaded the slides to Slide Share, or you can download the full presentation from my Sky Drive.

Links and resources

Unit Testing in Silverlight

Presentation Model / View Model

Dependency Injection

Wednesday, September 03, 2008 10:46:32 AM (W. Europe Daylight Time, UTC+02:00)
Hi Jonas,

Great talk at TechEd 2008 NZ, really appreciated it! Good level and excellent skills on show to really get people excited about the technology.

Cheers.
P
Pete
Wednesday, September 03, 2008 2:19:46 PM (W. Europe Daylight Time, UTC+02:00)
Hi Pete,

Thanks for some awesome feedback. Had a great time presenting in NZ. Glad you liked the level of the talk. Wasn't sure if it was too deep or focusing on too much "non core" stuff. Let me know if you have any questions regarding the content or the sample app :)
Thursday, September 04, 2008 3:23:56 PM (W. Europe Daylight Time, UTC+02:00)
Very nice looking example and slides. I'm giving a few Silverlight presentations at local user groups where I like (Ohio, USA) and I was wondering if I could use your demo and parts of your slides? I've been working on my own demo, but your hits all the points I was hoping to cover with much more polish than I would have been able to give them.
Thursday, September 04, 2008 3:43:12 PM (W. Europe Daylight Time, UTC+02:00)
Hi Matt!

Would be awesome if you would find the sample and slides useful for your presentation. Feel free to use it. The code is MS-PL licensed and everything else on this blog is Creative Commons licensed (attribution), so feel free to build on the content :)

A video recording of my TechEd talk is now available oneline at http://www.microsoft.com/nz/teched08/web.aspx?m=1 - So that might give you some ideas as well.

Good luck with your presentation!
Thursday, September 04, 2008 5:38:24 PM (W. Europe Daylight Time, UTC+02:00)
This is awesome -- it needs to be turned into a complete application so I can keep storing my divebook online! :)
Friday, September 05, 2008 12:35:21 AM (W. Europe Daylight Time, UTC+02:00)
Jonas ... Excellent presentation and code samples! I just put together a MVP example using Silverlight for some presentations this Fall. Interesting to see your perspective. Though my UI is not nearly as cool as your UI!
Saturday, September 06, 2008 3:19:16 PM (W. Europe Daylight Time, UTC+02:00)
@Rob Burke - Yeah, have been thinking about that. Would be awesome to build a proper S+S Dive Log application. A cool Silverlight UI to manage your dives, some ADO.NET Data Services to make the data available to build apps and widgets, and a WPF client side application to get logs off your dive computer... But the problem is always finding time for those projects... ;) But glad you liked the demo app!

@John Papa - Thanks for the feedback! Is your content available online? I'm more than happy to check it out and give some feedback.
Tuesday, September 09, 2008 1:54:37 AM (W. Europe Daylight Time, UTC+02:00)
Hi Jonas, that's one of the best sessions in TechEd this year - thanks again! I missed your morning WEB309 session in NZ due to problems with hotel billing - very glad your session was recorded!

One question though - I may be going blind but can't for the life of me find the sample code to download. Was it made available?

Cheers,
D.
Dany
Tuesday, September 09, 2008 2:05:20 AM (W. Europe Daylight Time, UTC+02:00)
Hi Dany,

First - Thanks for the great feedback! Glad you liked the session.

The code is available on this post, as an embedded download link from Windows Live Sky Drive. Perhaps I need to make this part a little bit more usable ;)

It's embedded directly under the screen shot of the demo application.

I've also included the link in this comment it make it easy to get:
http://i1nvhq.bay.livefilestore.com/y1pxeiLHE43mCvXk04sWEzv2JbCxTzC1Bt0XyIw7qxwWQ2A32RUrfVdpJB66Zdl1hmrdboHBtf6x84/DiveLog%20Silverlight%202%20Beta%202.zip?download

Tuesday, September 09, 2008 3:44:59 AM (W. Europe Daylight Time, UTC+02:00)
Thanks very much for the link - I completely missed it and assumed the second Sky Drive link includes code sample :o)

Thanks again.
Dany
Friday, September 12, 2008 11:56:01 AM (W. Europe Daylight Time, UTC+02:00)
Hi Jonas, I really enjoyed your session presented in Australia. It really got me going with Silverlight, and gave me a better understanding of how is provides for much easier developer/designer interaction.

Looking into your Dive Log app, I came across an issue I was hoping you could help out with. The VS designer does not display a preview for any new user controls added to the DiveLogDemo Silverlight project. With further investigation, I think I pinned it down to the ServiceLocator static resource declared in App.xaml. As soon as I remove the resource, previews start reappearing. The error list also shows a "undeclared prefix" message. Do you have any ideas why?
Mario
Friday, September 12, 2008 12:08:09 PM (W. Europe Daylight Time, UTC+02:00)
Hi Mario!

Glad you found my presentation useful!

Strange Mario. It doesn't run in VS2008 on my machine either. But mine is complaining about the Visual State Manager namespace. To be honest I've given up on the Visual Studio designer for Silverlight applications. I only use the XAML editor, but have turned off the XAML preview. The few times it actually works, it's really inaccurate, and doesn't pick up meta-data such as the "designer width" and "designer height" that Blend add. So if you don't have a set size for your you won't see anything in Visual Studio.

So my recommendation is to stick to Blend for wysiwyg even if your a developer. Microsoft have also announced that they will not be able to add allot of design time support in Visual Studio for the initial release of the tools. Hopefully the preview will be more performant, but you will not be able to visually position things or set properties in the properties window...

Let me know if you find a way to get the Visual Studio designer to play nice :)

Cheers,
Jonas
Monday, October 06, 2008 10:08:20 PM (W. Europe Daylight Time, UTC+02:00)
Hi Jonas,

Thanks for sharing this DiveLog demo. I really enjoyed watching you build it up in the video and have found the source code very educational. I'm working on my own Silverlight project that I started before viewing your presentation and source code. I took my own stab at using the ViewModel pattern and have it working fairly well, buy I didn't have the design time features you were able to create by using DI and the mock service. And I also didn't have the Command pattern implemented as you do. I really like these patterns and the features they enable, so I'm attempting to work them into my project using your source as a guide.

I have some questions about the project structure though. In DiveLegoDemo you have everything in one project - meaning the UI, the model/viewmodel and the services. When I started my project, I didn't want the UI directly referencing the service proxy, so I put the service reference and the viewmodel code in a separate project that the UI project references. My question is, do you think that's a good idea? Did you put everything in one project because it was a demo, or do you think that's the best structure in general? Also, I'm not exactly sure how to handle the commands with the two project structure. Do you have any advice in that regard?

Thanks,
Kevin Kuebler
Kevin
Wednesday, October 08, 2008 7:35:44 AM (W. Europe Daylight Time, UTC+02:00)
Hi Kevin,

I kept everything in one project because this was a small demo project, and because there is no re-usable parts in the project I want to use in an other application. If this was a bigger project I would definitely consider that separating things into multiple projects.

I can't see why that would cause any problems. The ViewModel isn't referencing the proxies directly, it's referencing and interface which is supplied by the IoC container.

For the commands you would have to create a separate library containing only the command framework pieces. The concrete commands you want to use would be implemented in the ViewModel library. The user interface would reference both the Command framework library, and the ViewModel library. It would need the Command library to get the CommandService.CommandName extension property, and of course the ViewModel to be able to bind against it.

I would probably put the IoC container in the UI application, as that is the "entry point" binding your application together.

Let me know how it works out :)
Wednesday, October 08, 2008 7:36:22 AM (W. Europe Daylight Time, UTC+02:00)
Hi Kevin,

I kept everything in one project because this was a small demo project, and because there is no re-usable parts in the project I want to use in an other application. If this was a bigger project I would definitely consider that separating things into multiple projects.

I can't see why that would cause any problems. The ViewModel isn't referencing the proxies directly, it's referencing and interface which is supplied by the IoC container.

For the commands you would have to create a separate library containing only the command framework pieces. The concrete commands you want to use would be implemented in the ViewModel library. The user interface would reference both the Command framework library, and the ViewModel library. It would need the Command library to get the CommandService.CommandName extension property, and of course the ViewModel to be able to bind against it.

I would probably put the IoC container in the UI application, as that is the "entry point" binding your application together.

Let me know how it works out :)
Thursday, October 09, 2008 4:50:29 PM (W. Europe Daylight Time, UTC+02:00)
Hi Jonas,

Well, so far it's working out pretty well. I actually decided to try wiring in the command service before seeing your reply. And I ended up with the same solution - I put the command framework classes in a separate library that both the UI and model projects referenced, and I put the concrete commands in the model library. That works great. And it was encouraging to see that I came up with the same solution as you! The only thing I did differently was put the IOC container in the model library. I see your point about the UI being the "entry point" though, so I may decide to move that.

I have another question though. One thing I wanted to do was to pull out some of the UI into user controls instead of having everything in one Page.xaml. I'm having trouble binding the ViewModel to the user control. I created a dependency property in the user control with the type of my ViewModel, and in the Page xaml where I create the user control I bind that property. The user control then sets the bindings for it's controls in it's xaml. But when I try to run that I get a XamlParseException. I noticed in the DiveLogDemo project you have a DiveTank user control but I don't quite get how that's working. It looks like you're setting up all the bindings on that in code, and only when it's running in the browser. Does that mean I can't do what I'm trying to do - declaratively bind my user control to the same view model as the page that contains it? That would be too bad if we couldn't get the design-time binding that we get in the main page for the user controls too.

Thanks again for your help! Overall, I really like using the ViewModel pattern with Silverlight and XAML.

Kevin Kuebler
Kevin
Friday, October 10, 2008 1:21:16 AM (W. Europe Daylight Time, UTC+02:00)
Hi Kevin,

The way you normally do it is simply by setting the DataContext property of the UserControl - No need for properties or anything special. So if your ViewModel is the DataContext of your Page.xaml, and you that ViewModel got a CurrentPerson property representing the currently selected Person object, you can pass it to your user control like this:

<my:Control DataContext="{Binding Path=CurrentPerson}" />

If you want to pass the entire DataContext from the parent to the child UserControl you simply do:

<my:Control DataContext="{Binding}" />

Inside your UserControl you set up your binding like normal, i.e. a TextBlock bound to FirstName (since you assume the DataContext will be a Person object).

The problem with this approach is that you don't get any good design-time support. You can work around this to set the DataContext inside the UserControl as well, to give you some design time data when working in Blend. Since you're re-setting the DataContext from your Page you won't use the dummy one anyway.

I used this approach on the YouCard application where I have a Card UserControl to represent each Twitter user. Check it out at http://jonas.follesoe.no/YouCardRevisitedImplementingTheViewModelPattern.aspx.

As for the Dive Tank user control that one if different... Let me try to explain: If you set the DataContext on the UserControl and use that for binding, the UserControl needs to know the name of the properties available to bind against. So a PersonUserControl will know that the Name textbox should bind against the Name field.

The Dive Tank control is written in such a way that it exposes a single Double property to set/get it's value, and you set up the binding OUTSIDE the control. So the Dive Tank control is usefull anytime you want to bind against a double value (just like a custom slider control), while a PersonUserControl would only be usefull for objects that has the correct "shape" (FirstName, LastName, Address etc).

So I guess what I'm doing with the Dive Tank is creating something more similar to a "real" control (but implemented as a User Control).

If think I'm only setting up the binding expressions when in run-time mode because of an old bug in Blend 2.5 - It used to crash at design time ;)

Monday, October 13, 2008 9:11:14 PM (W. Europe Daylight Time, UTC+02:00)
Hi Jonas,

I see what you're saying. This is one of those instances of trying to make it harder than it really is. :-) For some reason, it just didn't occur to me to bind the DataContext of the user control. That makes sense. I haven't tried it yet but will soon. I just got a new machine the other day and finished building it on Friday. But I didn't install the SL tools for Studio yet. Since the RTW is supposed to happen tomorrow, I'll wait to see if the tools are updated then too.

Also, I discovered another problem with the design time data binding support, at least in Beta 2. Hopefully it will be fixed in the final release. Using your technique I got the design time binding working, as I said before. But it turns out that controls that are inside of a TabItem control (in a TabControl) don't display their bound data in Blend. If I move them outside of the Tab control they display the data. But not when they're inside the tab. We'll see if that's fixed in the final release.

Thanks again for all your help. This has been a great learning experience!

Kevin Kuebler
Kevin
Tuesday, October 21, 2008 4:42:05 PM (W. Europe Daylight Time, UTC+02:00)
Hi Jonas,

I just wanted to report back that binding the DataContext of my user controls from within my page works great. I even seem to get design time binding in Blend, which I thought you had indicated wouldn't work. It seems to be working fine for me though, which is really nice.

Also, the issue I was having with the tab control not showing bound data in Blend may have actually been an issue with the style I was applying. In the final release I'm getting bound data showing up in the tab control in Blend, but not when I apply my style to it. I'm going to try to recreate the style in Blend to see if that fixes it. Thanks again!

Kevin
Kevin
Tuesday, October 21, 2008 5:34:42 PM (W. Europe Daylight Time, UTC+02:00)
Never mind what I said in my previous comment. I see what you mean now. :-)

The design time binding works fine for the user control when you're viewing the page that contains the user control. But you don't get anything when working on the control itself. I went ahead and added the DataContext in the user control's XAML the same way as the page is setup (referencing the service locator) to get binding when viewing the actual user control in Blend. It's kind of redundant but it works for now.

Kevin Kuebler
Kevin
Thursday, December 04, 2008 2:13:34 AM (W. Europe Standard Time, UTC+01:00)
Hi Jonas,

Interesting topic you have there. May I know will you update your DriveLog project for SL2 RTM version? Hope you can share it here. :)
Thursday, December 04, 2008 3:13:51 AM (W. Europe Standard Time, UTC+01:00)
Hi Patrick,

Thanks for the comment. Updated versions of my sample applications are available at http://jonas.follesoe.no/UpdatedSamplesAndSomeNuggetsFromTheArchive.aspx.
Saturday, May 30, 2009 4:49:41 PM (W. Europe Daylight Time, UTC+02:00)
Hi Jonas,
Excellent demo and a true learning experience! One of the best demos I have seen so far. I following and learning from it by watching over and over.
I am new to dependency injection and will be trying Ninject as you have shown.
But before I do that I taking step by step approach and want to write a client side unit test first before I implement Ninject. I was able to implement MVVM fine. In my test, I added
model.GetStudents("Anita");
EnqueueConditional(() => model.Students.Count > 5);
EnqueueTestComplete();
Assert.IsTrue(model.Students.Count > 0, "nnn");

but model.Student.Count is coming as 0. I think I have to make use of completed event from viewmodel first so that Audits are populated, but not sure how. I get the right results, but not from a test. How can I accomplish that. Thanks much!
manor
Tuesday, September 08, 2009 8:16:08 PM (W. Europe Daylight Time, UTC+02:00)
Hi Manor,

And thanks for the great comment! I'm really glad you find the presentation useful.

Your code looks correct - the EnqueueConditional should block the thread until your expression is true: that the number of Students are greater than 5.

Are you still experiencing problems with your ViewModel and testing?

-Jonas
Name
E-mail
(will show your gravatar icon)
Home page

Comment (Some html is allowed: a@href@title, strike) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

Enter the code shown (prevents robots):

Live Comment Preview
<March 2010>
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910