Background and Original Sample From Microsoft
Microsoft has put a huge amount of work into building hundreds of sample apps for us developers who are working in on Windows Store Apps (Applications that can be downloaded from the Windows 8 Store). Microsoft tried very hard to cover all the capabilities with good solid examples. Unfortunately, many of the apps are incomplete in many ways. I actually doubt if any of them would actually make it through the store certification process.
The area I am going to talk about now is how to take one of the Windows Store Apps (The Windows Blog Reader) and add design time support so that when you are looking at a XAML page in Visual Studio or Blend, it shows what it actually looks like instead of a blank screen.
Here is a zip file that was on msdn as of the writing of this blog post:
And here is what the page ItemsPage.xaml looks like in the designer (or Blend for that matter).
Adding Design Time Support
In order to add design time support, we need to first create a new class to replace the current FeedData class that currently reads actual feeds to get it’s information. The file FeedData.cs is the one we want to work on. We are going to hugely simplify it. It will not have any async tasks, it will not have an ObservableCollection of Feeds, it will just be a simple POCO (plain old c# object).
Here are the steps:
- Copy FeedData.cs to FeedDataDesignTime.cs
- In FeedData.cs, make Items updatable with a setter
- In ItemsPage.xaml, add a new source tag prefixed by d: which means it will be ignored at runtime (add to CollectionsViewSource section)
- To App.xaml, add another local resource FeedDataSourceDesignTime
- Fill in the code for FeedDataDesignTime.cs to be very simple
That’s it! you should not see the following when navigate to the ItemsPage.xaml in Visual Studio. Notice the grid is showing with your sample data.
Step By Step Details
Step 1and step 2 are self explanatory.
Step 3 basically change your CollectionViewSource to include a namespace (d) which will not be compiled because of the ignore statement in the xaml header. Your full CollectionViewSource now looks like the following. Notice it has two Source attributes. One that gets used at design time (the new one) and the original that has not changed which gets used at run time.
<CollectionViewSource x:Name="itemsViewSource" d:Source="{Binding Feeds, Source={d:DesignInstance Type=local:FeedDataSourceDesignTime, IsDesignTimeCreatable=True}}" Source="{Binding Items}"/>
Step 4 basically is to create a static in the main app class called FeedDataSourceDesignTime as follows. It also defines a key so we can reference that from our c# code. The reason we do this is so that this can be easily accessed from both c# and the xaml code itself (that is, declaring FeedDataSourceDesignTime declaratively in xml).
Step 5 is replacing the class FeedData.cs with FeedDataSourceDesignTime.cs make the data for the sample come from a local static array rather than making an async web call. It’s about 100 lines of code and I don’t want to paste it all here. It is in the root of the project attached below. To give you an idea of what it looks like, I’m pasting a piece of the class below.
namespace WindowsBlogReader { public class FeedDataSourceDesignTime { public List<FeedData> Feeds { get; set; }<span class="kwrd">public</span> FeedDataSourceDesignTime() { Feeds = <span class="kwrd">new</span> List<FeedData>(); DateTime dt = DateTime.Now; var feedDatas = <span class="kwrd">new</span> List<FeedData> { <span class="kwrd">new</span> FeedData { Description = <span class="str">"description1"</span>, PubDate = dt.Subtract(<span class="kwrd">new</span> TimeSpan(1, 1, 1)), Title = <span class="str">"title1"</span>, Items = <span class="kwrd">new</span> List<FeedItem>...</pre>
The Modified Visual Studio 2012 Project
Below is a link to the VS Project file with the above changes done. It also includes the full FeedDataSourceDesignTime class which you will of course need to write yourself for any project. Give it a try!
Download it and give it a try! When you actually run it, if any of the blog links are down, the await hangs forever so you might want to run it in the debugger to make sure all the links are good (and find the bad ones).
Stumbling Blocks
It’s really hard to figure out what is wrong if your data initialization code in your FeedDataSourceDesignTime.cs data creation is wrong. For example, I had created a uri as “new Uri(“peter.jpg”); and it took me about 2 hours to figure out that was the problem. I need a FQDN in front of the the name. A also at one point had forgotten to new up my List in the constructor of that class and I kept seeing “object null” violation which as happening when I was trying to do an AddRange to the List. Correct error, but practically impossible to figure out.
HTH’s!