Hub App – Working with Json Data

Welcome again! It’s little bit late, I’m writing this article. Today, I’m going to talk about “Handing Data with Json” and we’ll be working in Windows Phone “Hub App” template. It’s going to be fun to working 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’ve followed my previous articles, as a great Windows Phone developer your journey starts here. We’ll create an awesome app name “Letters of John Keats”. JK is one of my favorite poets and we’re going to make this app which will have the letters to his girl friend “Fanny Brawne”. So let’s get crack in “Hub App” working with “Json”.

First of all,m take a new project and select the “Hub App” template. Give it a name simply “HubApp”.

1

Now, you’ve all these files in your Solution Explorer.

2

So, first is first, we’ll replace the “SampleData.json” with our own file. Simple is to erase all the data in existing file and paste your desire data here. We’ve replace 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 not an opportunity of sending off a Letter which I wrote for you on Tuesday night-'twas too much like one out of Rousseau's Heloise. I am more reasonable this morning. The morning is the only proper time for me to write to a beautiful Girl whom I love so much: for at night, when the lonely day has closed, and the lonely, silent, unmusical Chamber is waiting to receive me as into a Sepulchre, then believe me my passion gets entirely the sway, then I would not have you see those Rhapsodies which I once thought it impossible I should ever give way to, and which I have often laughed at in another, for fear you should [think me] either too unhappy or perhaps a little mad.\n\nI am now at a very pleasant Cottage window, looking onto a beautiful hilly country, with a glimpse of the sea; the morning is very fine. I do not know how elastic my spirit might be, what pleasure I might have in living here and breathing and wandering as free as a stag about this beautiful Coast if the remembrance of you did not weigh so upon me I have never known any unalloy'd Happiness for many days together: the death or sickness of someone has always spoilt my hours-and now when none such troubles oppress me, it is you must confess very hard that another sort of pain should haunt me.\n\nAsk yourself my love whether you are not very cruel to have so entrammelled me, so destroyed my freedom. Will you confess this in the Letter you must write immediately, and do all you can to console me in i-make it rich as a draught of poppies to intoxicate me-write the softest words and kiss them that I may at least touch my lips where yours have been. For myself I know not how to express my devotion to so fair a form: I want a brighter word than bright, a fairer word than fair. I almost wish we were butterflies and liv'd but three summer days-three such days with you I could fill with more delight than fifty common years could ever contain. But however selfish I may feel, I am sure I could never act selfishly: as I told you a day or two before I left Hampstead, I will never return to London if my Fate does not turn up Pam or at least a Court-card. Though I could centre my Happiness in you, I cannot expect to engross your heart so entirely-indeed if I thought you felt as much for me as I do for you at this moment I do not think I could restrain myself from seeing you again tomorrow for the delight of one embrace.\n\nBut no-I must live upon hope and Chance. In case of the worst that can happen, I shall still love you-but what hatred shall I have for another!\n\nSome lines I read the other day are continually ringing a peal in my ears:\n\nTo see those eyes I prize above mine own\nDart favors on another-\n\nAnd those sweet lips (yielding immortal nectar)\nBe gently press'd by any but myself-\nThink, think Francesca, what a cursed thing\nIt were beyond expression!\n\nJ.\n\nDo write immediately. There is no Post from this Place, so you must address Post Office, Newport, Isle of Wight. I know before night I shall curse myself for having sent you so cold a Letter; yet it is better to do it as much in my senses as possible. Be as kind as the distance will permit to your\n\nPresent my Compliments to your mother, my love to Margaret and best remembrances to your Brother-if you please so."
            },
            {
                "Title": "July 8, 1819",
                "Subtitle": "Unknown",
                "Content": "My sweet Girl-Your Letter gave me more delight than any thing in the world but yourself could do; indeed I am almost astonished that any absent one should have that luxurious power over my senses which I feel. Even when I am not thinking of you I receive your influence and a tenderer nature stealing upon me. All my thoughts, my unhappiest days and nights have I find not at all cured me of my love of Beauty, but made it so intense that I am miserable that you are not with me: or rather breathe in that dull sort of patience that cannot be called Life.\n\nI never knew before, what such a love as you have made me feel, was; I did not believe in it; my Fancy was afraid of it, lest it should burn me up. But if you will fully love me, though there may be some fire, 'twill not be more than we can bear when moistened and bedewed with Pleasures.\n\nYou mention 'horrid people' and ask me whether it depend upon them whether I see you again. Do understand me, my love, in this. I have so much of you in my heart that I must turn Mentor when I see a chance of harm befalling you. I would never see any thing but Pleasure in your eyes, love on your lips, and Happiness in your steps. I would wish to see you among those amusements suitable to your inclinations and spirits; so that our loves might be a delight in the midst of Pleasures agreeable enough, rather than a resource from vexations and cares. But I doubt much, in case of the worst, whether I shall be philosopher enough to follow my own Lessons: if I saw my resolution give you a pain I could not.\n\nWhy may I not speak of your Beauty, since without that I could never have lov'd you? I cannot conceive any beginning of such love as I have for you but Beauty. There may be a sort of love for which, without the least sneer at it, I have the highest respect and can admire it in others: but it has not the richness, the bloom, the full form, the enchantment of love after my own heart. So let me speak of your Beauty, though to my own endangering; if you could be so cruel to me as to try elsewhere its Power.\n\nYou say you are afraid I shall think you do not love me-in saying this you make me ache the more to be near you. I am at the diligent use of my faculties here, I do not pass a day without sprawling some blank verse or tagging some rhymes; and here I must confess, that, (since I am on that subject,) I love you the more in that I believe you have liked me for my own sake and for nothing else. I have met with women whom I really think would like to be married to a Poem and to be given away by a Novel. I have seen your Comet, and only wish it was a sign that poor Rice would get well whose illness makes him rather a melancholy companion: and the more so as so to conquer his feelings and hide them from me, with a forc'd Pun.\n\nI kiss'd your Writing over in the hope you had indulg'd me by leaving a trace of honey. What was your dream? Tell it me and I will tell you the interpretation threreof.Ever yours, my love!\n\nDo not accuse me of delay-we have not here any opportunity of sending letters every day. Write speedily."
            }
        ]
    }
]
}

Here, is a sample data of our application. We’ve used “Json”. “Json” stands for JavaScript Object Notation. Json is 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 third brackets (“[]”), the last item doesn’t have comma at the end in line number 15. Mainly every last element doesn’t need comma at the end. You can declare as many items as you need, also you can have many group items. This is the basic format of “Json”. You can learn basics about “Json” at http://json.org.

So, out app local data is set, now we need to modify the class “SampleDataSouce.cs” like this.

// Sample Data Item Class
public class SampleDataItem
{
	public SampleDataItem(String title, String subtitle, String content)
	{
		this.Title = title;
		this.Subtitle = subtitle;
		this.Content = content;
	}

	public string Title { get; private set; }
	public string Subtitle { get; private set; }
	public string Content { get; private set; }

	public override string ToString()
	{
		return this.Title;
	}
}

// Sample Data Group Class
public class SampleDataGroup
{
	public SampleDataGroup(String title, String subtitle)
	{
		this.Title = title;
		this.Subtitle = subtitle;
		this.Items = new ObservableCollection<SampleDataItem>();
	}

	public string Title { get; private set; }
	public string Subtitle { get; private set; }
	public ObservableCollection<SampleDataItem> Items { get; private set; }

	public override string ToString()
	{
		return this.Title;
	}
}

public sealed class SampleDataSource
{
	private static SampleDataSource _sampleDataSource = new SampleDataSource();

	private ObservableCollection<SampleDataGroup> _groups = new ObservableCollection<SampleDataGroup>();
	public ObservableCollection<SampleDataGroup> Groups
	{
		get { return this._groups; }
	}

	public static async Task<IEnumerable<SampleDataGroup>> GetGroupsAsync()
	{
		await _sampleDataSource.GetSampleDataAsync();
		return _sampleDataSource.Groups;
	}

	public static async Task<SampleDataGroup> GetGroupAsync(string uniqueId)
	{
		await _sampleDataSource.GetSampleDataAsync();
		// Simple linear search is acceptable for small data sets
		var matches = _sampleDataSource.Groups.Where((group) => group.Title.Equals(uniqueId));
		if (matches.Count() == 1) return matches.First();
		return null;
	}

	public static async Task<SampleDataItem> GetItemAsync(string uniqueId)
	{
		await _sampleDataSource.GetSampleDataAsync();
		// Simple linear search is acceptable for small data sets
		var matches = _sampleDataSource.Groups.SelectMany(group => group.Items).Where((item) => item.Title.Equals(uniqueId));
		if (matches.Count() == 1) return matches.First();
		return null;
	}

	private async Task GetSampleDataAsync()
	{
		if (this._groups.Count != 0)
			return;

		Uri dataUri = new Uri("ms-appx:///DataModel/SampleData.json");

		StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(dataUri);
		string jsonText = await FileIO.ReadTextAsync(file);
		JsonObject jsonObject = JsonObject.Parse(jsonText);
		JsonArray jsonArray = jsonObject["Groups"].GetArray();

		foreach (JsonValue groupValue in jsonArray)
		{
			JsonObject groupObject = groupValue.GetObject();
			SampleDataGroup group = new SampleDataGroup(groupObject["Title"].GetString(),
														groupObject["Subtitle"].GetString());

			foreach (JsonValue itemValue in groupObject["Items"].GetArray())
			{
				JsonObject itemObject = itemValue.GetObject();
				group.Items.Add(new SampleDataItem(itemObject["Title"].GetString(),
												   itemObject["Subtitle"].GetString(),
												   itemObject["Content"].GetString()));
			}
			this.Groups.Add(group);
		}
	}
}

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 not an opportunity of sending off a Letter which I wrote for you on Tuesday night-'twas too much like one out of Rousseau's Heloise. I am more reasonable this morning. The morning is the only proper time for me to write to a beautiful Girl whom I love so much: for at night, when the lonely day has closed, and the lonely, silent, unmusical Chamber is waiting to receive me as into a Sepulchre, then believe me my passion gets entirely the sway, then I would not have you see those Rhapsodies which I once thought it impossible I should ever give way to, and which I have often laughed at in another, for fear you should [think me] either too unhappy or perhaps a little mad.",

					"I am now at a very pleasant Cottage window, looking onto a beautiful hilly country, with a glimpse of the sea; the morning is very fine. I do not know how elastic my spirit might be, what pleasure I might have in living here and breathing and wandering as free as a stag about this beautiful Coast if the remembrance of you did not weigh so upon me I have never known any unalloy'd Happiness for many days together: the death or sickness of some one has always spoilt my hours-and now when none such troubles oppress me, it is you must confess very hard that another sort of pain should haunt me.",

					"Ask yourself my love whether you are not very cruel to have so entrammelled me, so destroyed my freedom. Will you confess this in the Letter you must write immediately, and do all you can to console me in it-make it rich as a draught of poppies to intoxicate me-write the softest words and kiss them that I may at least touch my lips where yours have been. For myself I know not how to express my devotion to so fair a form: I want a brighter word than bright, a fairer word than fair. I almost wish we were butterflies and liv'd but three summer days-three such days with you I could fill with more delight than fifty common years could ever contain. But however selfish I may feel, I am sure I could never act selfishly: as I told you a day or two before I left Hampstead, I will never return to London if my Fate does not turn up Pam or at least a Court-card. Though I could centre my Happiness in you, I cannot expect to engross your heart so entirely-indeed if I thought you felt as much for me as I do for you at this moment I do not think I could restrain myself from seeing you again tomorrow for the delight of one embrace.",

					"But no-I must live upon hope and Chance. In case of the worst that can happen, I shall still love you-but what hatred shall I have for another!",

					"Some lines I read the other day are continually ringing a peal in my ears:",

					"To see those eyes I prize above mine own",
					"Dart favors on another-",
					"And those sweet lips (yielding immortal nectar)",
					"Be gently press'd by any but myself-",
					"Think, think Francesca, what a cursed thing",
					"It were beyond expression!",

					"J.",
					"Do write immediately. There is no Post from this Place, so you must address Post Office, Newport, Isle of Wight. I know before night I shall curse myself for having sent you so cold a Letter; yet it is better to do it as much in my senses as possible. Be as kind as the distance will permit to your",
					"Present my Compliments to your mother, my love to Margaret and best remembrances to your Brother-if you please so."
				]
            }
        ]
    }
]
}

Then, you have 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("\"", "")));
}

I personally don’t like to do that, because you can’t use double quote and “\n” or “\r” in this case. Or you may find it helpful in some cases.

Now, we’ll modify the “HubPage.xaml” first. We don’t need the other sections of “HubPage.xaml” for our appliction.

<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>

Lemme explain, what I’ve done here. In line number 9, you can see that we’ve bound header element with “Subtitle”. It’s actually “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 “Items” data. And in line number in line number 14 we’ve a click event name “ItemView_ItemClick”. When you click an item, it’ll bring the “ItemPage.xaml” to view the details of Items. In line number 19 & 20 we’ve bound the value “Title” & “Subtitle”. In line number 21 we’ve used a line to separate the items title and subtile with different items.

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)
{
	// Navigate to the appropriate destination page, configuring the new page
	// by passing required information as a navigation parameter
	var itemTitle = ((SampleDataItem)e.ClickedItem).Title;
	if (!Frame.Navigate(typeof(ItemPage), itemTitle))
	{
		throw new Exception(this.resourceLoader.GetString("NavigationFailedExceptionMessage"));
	}
}

Here in line number 5, we declare a variable “itemTitle” and set it to the title of “Items”, and pass it through the “Frame.Navigation()” as a parameter in line number 6. We don’d need the “GroupSection_ItemClick” event because we aren’t using “SectionPage.xaml” in our application. So we’re working only two different pages, first is “HubPage.xaml” and second is “ItemPage.xaml”. So, you can understand that you got some real power to to present a lots of data simply in two pages. So DataBinding and Json give us lots of flexibility to make our apps much faster and efficient.

Now, were gonna modify our “ItemPage.xaml”, just put 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>

Here, the we’ve three TextBlocks, and first one is showing the items “Title”, second one is “Subtitle” and third one is “Content” which contains the letter body. We surround the TextBlocks with a StackPanel and ScrollViewer so that, you can see long text with scrolling option. One important thing is in line number 5 we’ve used TextWrapping to “Wrap” so that, the texts fit in the window size.

One more extra thing you can do is to modify your “SectionPage.xaml”. Though I’m not using this page, just showing if you want to use. 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>

We just used the “Title” & “Subtitle” section. 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"));
	}
}

We’ve declare a variable “itemTitle” and pass it through navigation. That’s it.

Now change the “Header.Text” & “Hub.Header” in “Strings>>en-US>>Resources.resw” like this.

5

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 like below.

<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>

here, we changed the background of the app, just by changing the picture. You’ll find it in the “Assets” folder or you can upload your own choose picture. Also we changed the opacity to “0.3” so the background becomes darker than as it is.

Now your design should look like this.

4

Now we’re all set. If we, run the application, it looks just awesome like this.

a

b

So, we just made a rich “Json Data Hub” application doing few modification of “Hub App” template. I personally make an app about my favorite poet John Keats’ letters to his girl friend 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. Till then good bye. Have a nice day.

Happy Coding!

You can download the full source code from here,
Download link: http://1drv.ms/1vXO4R2

Leave a comment