Introduction
Welcome again! Today, I'm going to talk about handling data in JavaScript Object Notation (JSON) format and we'll be using the Windows Phone “Hub App” template. It's going to be fun to work with this awesome template and I hope after exploring the “Hub App” and “JSON Data”, you'll be able to do your own stuff and write a great Windows Phone App. If you have followed my previous articles, as a great Windows Phone developer your journey starts here. We'll create an awesome app called “Letters of John Keats”. JK is one of my favorite poets and we're going to make this app that will have the letters to his girlfriend “Fanny Brawne”. So let's get cracking on “Hub App” working with “JSON”.
Creating a New Project
First of all create a new project and select the “Hub App” template. Provide it the name “HubApp”.
Figure 1
You now have all the following files in your Solution Explorer.
Figure 2
Working with JSON Data
So, first is first, we'll replace the “SampleData.json” with our own file. The simple way to do that is to erase all the data in the existing file and paste your data there. We will replace it with our own data here.
- {"Groups":[
- {
- "Title": "Letters of John Keats",
- "Subtitle": "Selected Love Letters to Fanny Brawne",
- "Items": [
- {
- "Title": "July 3, 1819",
- "Subtitle": "Shanklin, Isle of Wight, Thursday",
- "Content": "My dearest Lady - I am glad I had ... please so."
- }
- ]
- }
- ]
- }
Listing 1
Here is sample data for our application. We've used the JSON format. JSON is a lightweight data interchange format. If you notice, you can realize that “JSON” is nothing but an “Array” object. Here, the “Items” has two items and the items are surrounded by square brackets (“[]”), the last item doesn't have a comma at the end in line number 15. Mainly every last element doesn't need a comma at the end. You can declare as many items as you need. You can also have many group items. This is the basic format of “JSON”. You can learn the basics of JSON at:
Introducing JSON.Retrieving the JSON Data
So, our app local data is set, now we need to modify the class “SampleDataSouce.cs” like this.
Different JSON Approach
Another approach of “JSON” you can have is given below.
- {"Groups":[
- {
- "Title": "Letters of John Keats",
- "Subtitle": "Selected Love Letters to Fanny Brawne",
- "Items": [
- {
- "Title": "July 3, 1819",
- "Subtitle": "Shanklin, Isle of Wight, Thursday",
- "Content":
- [
- "My dearest Lady - I am glad I had ... little mad.",
- ...
- "Present my Compliments to your mother, ... so."
- ]
- }
- ]
- }
- ]
- }
Listing 3
Then, you need to change this line of code in “SampleDataSouce.cs”.
- foreach (JsonValue itemValue in groupObject["Items"].GetArray())
- {
- JsonObject itemObject = itemValue.GetObject();
- group.Items.Add(new SampleDataItem(itemObject["Title"].GetString(),
- itemObject["Subtitle"].GetString(),
- itemObject["Content"].Stringify().Replace("[", "").Replace("]", "").Replace("\",", "\n").Replace("\"", "")));
- }
Listing 4
I personally don't like to do that, because you can't use double quotes and “\n” or “\r” in this case. Or you may find it helpful in some cases.
Working with “HubPage.xaml”
Now, we'll modify the “HubPage.xaml” first. We don't need the other sections of “HubPage.xaml” for our application.
- <Page.Resources>
- <DataTemplate x:Key="HubSectionHeaderTemplate">
- <TextBlock Margin="0,0,0,-9.5" Text="{Binding}"/>
- </DataTemplate>
- </Page.Resources>
-
- <Grid x:Name="LayoutRoot">
- <Hub x:Name="Hub" x:Uid="Hub" Header="application name" Background="{ThemeResource HubBackgroundImageBrush}">
- <HubSection x:Uid="HubSection1" Header="{Binding Subtitle}" DataContext="{Binding Groups[0]}" HeaderTemplate="{ThemeResource HubSectionHeaderTemplate}" Width="400">
- <DataTemplate>
- <ListView
- ItemsSource="{Binding Items}"
- IsItemClickEnabled="True"
- ItemClick="ItemView_ItemClick"
- ContinuumNavigationTransitionInfo.ExitElementContainer="True">
- <ListView.ItemTemplate>
- <DataTemplate>
- <StackPanel Grid.Column="1" Margin="14.5,0,0,0">
- <TextBlock Text="{Binding Title}" Style="{ThemeResource ListViewItemTextBlockStyle}"/>
- <TextBlock Padding="10" Text="{Binding Subtitle}" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}"/>
- <Line x:Name="line" X1="0" Y1="5" X2="365" Y2="5" Stroke="Brown" StrokeThickness="2"></Line>
- </StackPanel>
- </DataTemplate>
- </ListView.ItemTemplate>
- </ListView>
- </DataTemplate>
- </HubSection>
- </Hub>
- </Grid>
Listing 5
Let me explain what I've done here. In line number 9, you can see that we've bound the header element with “Subtitle”. It's actually the “Groups'” subtitle because our “Datacontext” is “Groups[0]” index, the first group content. In line number {??} we've bound “ItemSource” to “Items”, so it'll fetch all the “Items” data. And in line number 14 is a a click event named “ItemView_ItemClick”. When you click an item, it'll bring the “ItemPage.xaml” to view the details of Items. In line numbers 19 & 20 we bound the value “Title” and “Subtitle”. Line number 21 uses a line to separate the items title and subtitle from other items.
Figure 3
Now if we look at the “HubPage.xaml.cs”, we just modify the “ItemView_ItemClick” event like this.
- private void ItemView_ItemClick(object sender, ItemClickEventArgs e)
- {
-
-
- var itemTitle = ((SampleDataItem)e.ClickedItem).Title;
- if (!Frame.Navigate(typeof(ItemPage), itemTitle))
- {
- throw new Exception(this.resourceLoader.GetString("NavigationFailedExceptionMessage"));
- }
- }
Listing 6
Here in line number 5, we declare a variable “itemTitle” and set it to the title of “Items” and it using the “Frame.Navigation()” as a parameter in line number 6. We don't need the “GroupSection_ItemClick” event because we aren't using “SectionPage.xaml” in our application. So we're working on just two pages, the first is “HubPage.xaml” and the second is “ItemPage.xaml”. So, you can understand that you have some real power to present a lot of data simply in two pages. So DataBinding and JSON gives us lots of flexibility to make our apps much faster and efficient.
Working with “ItemPage.xaml”
We will now modify our “ItemPage.xaml”, just use these three lines of code.
- <ScrollViewer>
- <StackPanel Grid.Column="1" Margin="14.5,0,0,0">
- <TextBlock Text="{Binding Title}" Style="{ThemeResource ListViewItemTextBlockStyle}"/>
- <TextBlock Padding="10,0,0,20" Text="{Binding Subtitle}" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}"/>
- <TextBlock Padding="0,0,0,10" TextWrapping="Wrap" Text="{Binding Content}" FontSize="20" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}"/>
- </StackPanel>
- </ScrollViewer>
Listing 7
Here, then we've three TextBlocks and the first one is showing the items “Title”, the second one is “Subtitle” and the third one is “Content” that contains the letter body. We surround the TextBlocks with a StackPanel and ScrollViewer so that you can see the long text with the scrolling option. One important thing is in line number 5 we've used TextWrapping to “Wrap” so that the text fit in the window size.
Working with “Sectionpage.xaml”
One more extra thing you can do is to modify your “SectionPage.xaml”. Though I'm not using this page, just showing it if you do want to use it. Modify the “SectionPage.xaml” like this, here is only “ListView”.
- <ListView
- x:Name="itemListView"
- AutomationProperties.AutomationId="ItemListView"
- AutomationProperties.Name="Items In Group"
- TabIndex="1"
- Grid.Row="1"
- ItemsSource="{Binding Items}"
- IsItemClickEnabled="True"
- ItemClick="ItemView_ItemClick"
- SelectionMode="None"
- IsSwipeEnabled="false"
- Margin="19,0,0,0">
- <ListView.ItemTemplate>
- <DataTemplate>
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto"/>
- <ColumnDefinition Width="*"/>
- </Grid.ColumnDefinitions>
-
- <StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10,0,0,0">
- <TextBlock Text="{Binding Title}" Style="{ThemeResource ListViewItemTextBlockStyle}"/>
- <TextBlock Text="{Binding Subtitle}" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}"/>
- </StackPanel>
- </Grid>
- </DataTemplate>
- </ListView.ItemTemplate>
- </ListView>
Listing 8
We just used the “Title” and “Subtitle” sections. Also the “ItemView_ItemClick” event in “SectionPage.xaml.cs” like this.
- private void ItemView_ItemClick(object sender, ItemClickEventArgs e)
- {
- var itemTitle = ((SampleDataItem)e.ClickedItem).Title;
- if (!Frame.Navigate(typeof(ItemPage), itemTitle))
- {
- var resourceLoader = ResourceLoader.GetForCurrentView("Resources");
- throw new Exception(resourceLoader.GetString("NavigationFailedExceptionMessage"));
- }
- }
Listing 9
We've declared a variable “itemTitle” and ed it using navigation. That's it.
Working with Phone Resources
Now change the “Header.Text” and “Hub.Header” in “Strings>>en-US>>Resources.resw” like this.
Figure 4
Working with “App.xaml”
Also, we want to change the background of our app, so that it looks more beautiful and readable. Go to “App.xaml” and change the background as in the following.
- <Application.Resources>
- <ResourceDictionary>
- <ResourceDictionary.ThemeDictionaries>
- <ResourceDictionary x:Key="Default">
- <ImageBrush x:Key="HubBackgroundImageBrush" ImageSource="Assets/HubBackground.theme-light.png" Opacity="0.3"/>
- </ResourceDictionary>
- <ResourceDictionary x:Key="HighContrast">
- <ImageBrush x:Key="HubBackgroundImageBrush" ImageSource="{x:Null}"/>
- </ResourceDictionary>
- </ResourceDictionary.ThemeDictionaries>
-
- </ResourceDictionary>
- </Application.Resources>
Listing 10
Here, we change the background of the app, just by changing the picture. You'll find it in the “Assets” folder or you can upload your own picture. Also, we changed the opacity to “0.3” so the background becomes darker than it really is.
Now your design should look like this.
Figure 5
Running the Application
Now we're all set. If we run the application, it looks just awesome like this.
Figure 6
Summary
So, we just made a rich “JSON Data Hub” application by doing a few modifications of the “Hub App” template. I personally made an app about my favorite poet John Keats' letters to his girlfriend Fanny Brawne and you can make your own data bound app like this.
Hopefully you've enjoyed this. That's it for today. I'll be here with a new topic soon. Until then good bye. Have a nice day.
Happy Coding!