Hi again, in this part I will go through setting up the Silverlight application in Visual Studio and create the WCF services needed to consume the XML data from Umbraco.
First off, let’s create a new Silverlight Navigation Application. You could go for a regular Silverlight application and make some custom navigation, but as I see it, there’s no reason not to make use of the Navigation framework that comes with Silverlight version 3+.
When hitting the ‘OK’ button it prompts you to choose if you want to host the Silverlight app in a new Website, which we certainly would like to!
Now that we have our new solution containing a Silverlight application and a website that hosts it, we can start adding business classes, services, viewmodels, views and so on, so forth. This is my humble, very simplified structure:
Notice that the Model (business classes) and Services are just folders in the web project. This is for the sake of demonstration and I do not recommend you to do this in a production, large-scale environment – instead I would recommend you to split it up in projects i.e. SilverlightUmbraco.Services, SilverlightUmbraco.Services.Contracts, SilverlightUmbraco.Model and reference these where they are needed.
At first, let’s dig into the Model and Services folders:
We have to sort of ‘mirror’ the document types in Umbraco. As shown in the above image I have a NewsItem class, a TextPage class and a Menu class which are containing properties to store the data needed from Umbraco. I.e. the Menu class looks like this:
Simply three string properties containing the name of the menu item, the url to a page and the alias of the page which I will talk about later on.
Same goes for the TextPage and NewsItem classes, with the respective properties needed.
Now, the services job is quite simple: consume data and return objects. Let’s have a look at the MenuService:
First off we tell the service to load XML data from a given source, in this case the XML from Umbraco as shown in the first part:
We loop through the collection of <navigationItem> elements and add a new Menu object to a List which we return at the end. Simple stuff! Note that the service needs the full path to the XML data.
Again, same goes for the TextPage and NewsItem services. Although the TextPage is a bit different because it takes a URL parameter to know which Umbraco textpage it needs to read the XML from – more on this later.
Now, let us have a peek at the Silverlight Navigation Application:
For this I am using a simple MVVM structure containing the ViewModels folder and a Views folder. If you want to know more about this pattern, just do a search on ‘MVVM’ on google.com and you should have enough pages to read for the next few decades
We still need to compare the Silverlight application to our Umbraco installation and to do that we need to have a MenuViewModel, NewsViewModel and a TextPageViewModel and the following views: MenuView, NewsView and TextPageView.:
At first we have to set the MenuView’s datacontext to the MenuViewModel and tell it to get the menu items:
The MenuView and MenuViewModel will be our “anchor” when it comes to navigation in that we have to know the difference between a TextPage view and a News view – that’s where the Alias property comes into play. The Alias property is basically the nodeTypeAlias from the document type, i.e a TextPage will have the alias ‘umbTextPage’. If we take a look at the XAML for the MenuView we will see that we have to make use of the Tag and CommandParameter properties on a button (even though I don’t use commanding in this example) we are binding the Tag property to the url for the Umbraco page i.e. /getting-started.aspx or /news.aspx. The CommandParameter property is bound to the Alias to tell us what “type of page” we need to show.
When it comes to navigating I’m using a switch on the MenuViewModel that looks at the alias of the button clicked and tells the MainPage’s navigationframe to navigate to the corresponding view like this:
This is where MVVM purists will preach for hours and hours about best practices because essentially the ViewModels shouldn’t know anything about the View which it clearly does here by referencing the MainPage. If anyone knows of a better solution to this, I would be more than happy to hear from you J
I should also note that I have set up the navigation frame’s uri mapping in the App.xaml which looks like this:
It makes the urls more userfriendly after all.
As you can see in the above image, we’re trying to load the TextPageView with a url parameter. This parameter is basically the url to the umbraco text page, i.e. “/installing-modules.aspx” and is used by the TextPageService to get the XML data, create the TextPage object and return it to the TextPageViewModel’s TextPage property. So this will be the workflow when we want to show a TextPage:
In the TextPageView loaded event we can get the querystring which contains the Umbraco text page url as shown above. Then we can call the GetTextPage(string url) method on the TextPageViewModel which fetches the XML data for the given url and sets the TextPage property to the object returned from the service. Like this:
Then at last, we can set up the bindings as we like on the TextPageView:
I hope this gives an idea of the workflow in the Silverlight application. If you have any questions, please feel free to contact me J In the next post I will go through the final steps to get the application up and running in Umbraco.