diff --git a/9781430250340.jpg b/9781430250340.jpg
new file mode 100644
index 0000000..9d9b2f6
Binary files /dev/null and b/9781430250340.jpg differ
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..714d53f
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,27 @@
+Freeware License, some rights reserved
+
+Copyright (c) 2012 Adam Freeman
+
+Permission is hereby granted, free of charge, to anyone obtaining a copy
+of this software and associated documentation files (the "Software"),
+to work with the Software within the limits of freeware distribution and fair use.
+This includes the rights to use, copy, and modify the Software for personal use.
+Users are also allowed and encouraged to submit corrections and modifications
+to the Software for the benefit of other users.
+
+It is not allowed to reuse, modify, or redistribute the Software for
+commercial use in any way, or for a user’s educational materials such as books
+or blog articles without prior permission from the copyright holder.
+
+The above copyright notice and this permission notice need to be included
+in all copies or substantial portions of the software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..183f828
--- /dev/null
+++ b/README.md
@@ -0,0 +1,15 @@
+#Apress Source Code
+
+This repository accompanies [*Windows 8 Apps Revealed Using XAML and C#*](http://www.apress.com/9781430250340) by Adam Freeman (Apress, 2012).
+
+![Cover image](9781430250340.jpg)
+
+Download the files as a zip using the green button, or clone the repository to your machine using Git.
+
+##Releases
+
+Release v1.0 corresponds to the code in the published book, without corrections or updates.
+
+##Contributions
+
+See the file Contributing.md for more information on how you can contribute to this repository.
diff --git a/Source Code/Chapter 1/GrocerApp/GrocerApp.sln b/Source Code/Chapter 1/GrocerApp/GrocerApp.sln
new file mode 100644
index 0000000..9185511
--- /dev/null
+++ b/Source Code/Chapter 1/GrocerApp/GrocerApp.sln
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 2012 for Windows 8
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrocerApp", "GrocerApp\GrocerApp.csproj", "{2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|ARM = Debug|ARM
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|ARM = Release|ARM
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|ARM.ActiveCfg = Debug|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|ARM.Build.0 = Debug|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|ARM.Deploy.0 = Debug|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x64.ActiveCfg = Debug|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x64.Build.0 = Debug|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x64.Deploy.0 = Debug|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x86.ActiveCfg = Debug|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x86.Build.0 = Debug|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x86.Deploy.0 = Debug|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|ARM.ActiveCfg = Release|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|ARM.Build.0 = Release|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|ARM.Deploy.0 = Release|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x64.ActiveCfg = Release|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x64.Build.0 = Release|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x64.Deploy.0 = Release|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x86.ActiveCfg = Release|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x86.Build.0 = Release|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x86.Deploy.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Source Code/Chapter 1/GrocerApp/GrocerApp.v11.suo b/Source Code/Chapter 1/GrocerApp/GrocerApp.v11.suo
new file mode 100644
index 0000000..7d88d92
Binary files /dev/null and b/Source Code/Chapter 1/GrocerApp/GrocerApp.v11.suo differ
diff --git a/Source Code/Chapter 1/GrocerApp/GrocerApp/App.xaml b/Source Code/Chapter 1/GrocerApp/GrocerApp/App.xaml
new file mode 100644
index 0000000..822c131
--- /dev/null
+++ b/Source Code/Chapter 1/GrocerApp/GrocerApp/App.xaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 1/GrocerApp/GrocerApp/App.xaml.cs b/Source Code/Chapter 1/GrocerApp/GrocerApp/App.xaml.cs
new file mode 100644
index 0000000..cc3e603
--- /dev/null
+++ b/Source Code/Chapter 1/GrocerApp/GrocerApp/App.xaml.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Windows.ApplicationModel;
+using Windows.ApplicationModel.Activation;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+using Windows.UI.Xaml.Data;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Navigation;
+
+namespace GrocerApp {
+
+ sealed partial class App : Application {
+
+ public App() {
+ this.InitializeComponent();
+ this.Suspending += OnSuspending;
+ }
+
+ protected override void OnLaunched(LaunchActivatedEventArgs args) {
+ Frame rootFrame = Window.Current.Content as Frame;
+
+
+ if (rootFrame == null) {
+ // Create a Frame to act as the navigation context and navigate to the first page
+ rootFrame = new Frame();
+
+ if (args.PreviousExecutionState == ApplicationExecutionState.Terminated) {
+ //TODO: Load state from previously suspended application
+ }
+
+ // Place the frame in the current Window
+ Window.Current.Content = rootFrame;
+ }
+
+ if (rootFrame.Content == null) {
+
+ if (!rootFrame.Navigate(typeof(MainPage), args.Arguments)) {
+ throw new Exception("Failed to create initial page");
+ }
+ }
+ // Ensure the current window is active
+ Window.Current.Activate();
+ }
+
+ private void OnSuspending(object sender, SuspendingEventArgs e) {
+ var deferral = e.SuspendingOperation.GetDeferral();
+ //TODO: Save application state and stop any background activity
+ deferral.Complete();
+ }
+ }
+}
diff --git a/Source Code/Chapter 1/GrocerApp/GrocerApp/Assets/Logo.png b/Source Code/Chapter 1/GrocerApp/GrocerApp/Assets/Logo.png
new file mode 100644
index 0000000..e26771c
Binary files /dev/null and b/Source Code/Chapter 1/GrocerApp/GrocerApp/Assets/Logo.png differ
diff --git a/Source Code/Chapter 1/GrocerApp/GrocerApp/Assets/SmallLogo.png b/Source Code/Chapter 1/GrocerApp/GrocerApp/Assets/SmallLogo.png
new file mode 100644
index 0000000..1eb0d9d
Binary files /dev/null and b/Source Code/Chapter 1/GrocerApp/GrocerApp/Assets/SmallLogo.png differ
diff --git a/Source Code/Chapter 1/GrocerApp/GrocerApp/Assets/SplashScreen.png b/Source Code/Chapter 1/GrocerApp/GrocerApp/Assets/SplashScreen.png
new file mode 100644
index 0000000..c951e03
Binary files /dev/null and b/Source Code/Chapter 1/GrocerApp/GrocerApp/Assets/SplashScreen.png differ
diff --git a/Source Code/Chapter 1/GrocerApp/GrocerApp/Assets/StoreLogo.png b/Source Code/Chapter 1/GrocerApp/GrocerApp/Assets/StoreLogo.png
new file mode 100644
index 0000000..dcb6727
Binary files /dev/null and b/Source Code/Chapter 1/GrocerApp/GrocerApp/Assets/StoreLogo.png differ
diff --git a/Source Code/Chapter 1/GrocerApp/GrocerApp/Common/StandardStyles.xaml b/Source Code/Chapter 1/GrocerApp/GrocerApp/Common/StandardStyles.xaml
new file mode 100644
index 0000000..85f4ed6
--- /dev/null
+++ b/Source Code/Chapter 1/GrocerApp/GrocerApp/Common/StandardStyles.xaml
@@ -0,0 +1,1829 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mouse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 1/GrocerApp/GrocerApp/GrocerApp.csproj b/Source Code/Chapter 1/GrocerApp/GrocerApp/GrocerApp.csproj
new file mode 100644
index 0000000..465beb4
--- /dev/null
+++ b/Source Code/Chapter 1/GrocerApp/GrocerApp/GrocerApp.csproj
@@ -0,0 +1,151 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}
+ AppContainerExe
+ Properties
+ GrocerApp
+ GrocerApp
+ en-US
+ 512
+ {BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ GrocerApp_TemporaryKey.pfx
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE;NETFX_CORE
+ prompt
+ 4
+
+
+ true
+ bin\ARM\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ ARM
+ false
+ prompt
+ true
+
+
+ bin\ARM\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ ARM
+ false
+ prompt
+ true
+
+
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ x64
+ false
+ prompt
+ true
+
+
+ bin\x64\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ x64
+ false
+ prompt
+ true
+
+
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ x86
+ false
+ prompt
+ true
+
+
+ bin\x86\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ x86
+ false
+ prompt
+ true
+
+
+
+
+
+
+ App.xaml
+
+
+ MainPage.xaml
+
+
+
+
+
+ Designer
+
+
+
+
+
+
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+ 11.0
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 1/GrocerApp/GrocerApp/GrocerApp.csproj.user b/Source Code/Chapter 1/GrocerApp/GrocerApp/GrocerApp.csproj.user
new file mode 100644
index 0000000..b29230c
--- /dev/null
+++ b/Source Code/Chapter 1/GrocerApp/GrocerApp/GrocerApp.csproj.user
@@ -0,0 +1,6 @@
+
+
+
+ True
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 1/GrocerApp/GrocerApp/GrocerApp_TemporaryKey.pfx b/Source Code/Chapter 1/GrocerApp/GrocerApp/GrocerApp_TemporaryKey.pfx
new file mode 100644
index 0000000..27d6028
Binary files /dev/null and b/Source Code/Chapter 1/GrocerApp/GrocerApp/GrocerApp_TemporaryKey.pfx differ
diff --git a/Source Code/Chapter 1/GrocerApp/GrocerApp/MainPage.xaml b/Source Code/Chapter 1/GrocerApp/GrocerApp/MainPage.xaml
new file mode 100644
index 0000000..ce5eb15
--- /dev/null
+++ b/Source Code/Chapter 1/GrocerApp/GrocerApp/MainPage.xaml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 1/GrocerApp/GrocerApp/MainPage.xaml.cs b/Source Code/Chapter 1/GrocerApp/GrocerApp/MainPage.xaml.cs
new file mode 100644
index 0000000..b362acf
--- /dev/null
+++ b/Source Code/Chapter 1/GrocerApp/GrocerApp/MainPage.xaml.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+using Windows.UI.Xaml.Data;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Navigation;
+
+
+namespace GrocerApp {
+ public sealed partial class MainPage : Page {
+ public MainPage() {
+ this.InitializeComponent();
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+ }
+
+ private void ButtonClick(object sender, RoutedEventArgs e) {
+
+ FirstButton.Content = "Pressed";
+ FirstButton.FontSize = 50;
+
+ System.Diagnostics.Debug.WriteLine("Button Clicked: "
+ + ((Button)e.OriginalSource).Content);
+ }
+
+ }
+}
diff --git a/Source Code/Chapter 1/GrocerApp/GrocerApp/Package.appxmanifest b/Source Code/Chapter 1/GrocerApp/GrocerApp/Package.appxmanifest
new file mode 100644
index 0000000..518710a
--- /dev/null
+++ b/Source Code/Chapter 1/GrocerApp/GrocerApp/Package.appxmanifest
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+ GrocerApp
+ adam
+ Assets\StoreLogo.png
+
+
+
+ 6.2.1
+ 6.2.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 1/GrocerApp/GrocerApp/Properties/AssemblyInfo.cs b/Source Code/Chapter 1/GrocerApp/GrocerApp/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..f2e348e
--- /dev/null
+++ b/Source Code/Chapter 1/GrocerApp/GrocerApp/Properties/AssemblyInfo.cs
@@ -0,0 +1,29 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GrocerApp")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("GrocerApp")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp.sln b/Source Code/Chapter 2/GrocerApp/GrocerApp.sln
new file mode 100644
index 0000000..9185511
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp.sln
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 2012 for Windows 8
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrocerApp", "GrocerApp\GrocerApp.csproj", "{2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|ARM = Debug|ARM
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|ARM = Release|ARM
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|ARM.ActiveCfg = Debug|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|ARM.Build.0 = Debug|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|ARM.Deploy.0 = Debug|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x64.ActiveCfg = Debug|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x64.Build.0 = Debug|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x64.Deploy.0 = Debug|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x86.ActiveCfg = Debug|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x86.Build.0 = Debug|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x86.Deploy.0 = Debug|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|ARM.ActiveCfg = Release|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|ARM.Build.0 = Release|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|ARM.Deploy.0 = Release|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x64.ActiveCfg = Release|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x64.Build.0 = Release|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x64.Deploy.0 = Release|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x86.ActiveCfg = Release|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x86.Build.0 = Release|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x86.Deploy.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp.v11.suo b/Source Code/Chapter 2/GrocerApp/GrocerApp.v11.suo
new file mode 100644
index 0000000..fdda48b
Binary files /dev/null and b/Source Code/Chapter 2/GrocerApp/GrocerApp.v11.suo differ
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/App.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/App.xaml
new file mode 100644
index 0000000..fc45fa5
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/App.xaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/App.xaml.cs b/Source Code/Chapter 2/GrocerApp/GrocerApp/App.xaml.cs
new file mode 100644
index 0000000..4011f65
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/App.xaml.cs
@@ -0,0 +1,48 @@
+using System;
+using Windows.ApplicationModel;
+using Windows.ApplicationModel.Activation;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace GrocerApp {
+
+ sealed partial class App : Application {
+
+ public App() {
+ this.InitializeComponent();
+ this.Suspending += OnSuspending;
+ }
+
+ protected override void OnLaunched(LaunchActivatedEventArgs args) {
+ Frame rootFrame = Window.Current.Content as Frame;
+
+
+ if (rootFrame == null) {
+ // Create a Frame to act as the navigation context and navigate to the first page
+ rootFrame = new Frame();
+
+ if (args.PreviousExecutionState == ApplicationExecutionState.Terminated) {
+ //TODO: Load state from previously suspended application
+ }
+
+ // Place the frame in the current Window
+ Window.Current.Content = rootFrame;
+ }
+
+ if (rootFrame.Content == null) {
+
+ if (!rootFrame.Navigate(typeof(Pages.ListPage), args.Arguments)) {
+ throw new Exception("Failed to create initial page");
+ }
+ }
+ // Ensure the current window is active
+ Window.Current.Activate();
+ }
+
+ private void OnSuspending(object sender, SuspendingEventArgs e) {
+ var deferral = e.SuspendingOperation.GetDeferral();
+ //TODO: Save application state and stop any background activity
+ deferral.Complete();
+ }
+ }
+}
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/Assets/Logo.png b/Source Code/Chapter 2/GrocerApp/GrocerApp/Assets/Logo.png
new file mode 100644
index 0000000..e26771c
Binary files /dev/null and b/Source Code/Chapter 2/GrocerApp/GrocerApp/Assets/Logo.png differ
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/Assets/SmallLogo.png b/Source Code/Chapter 2/GrocerApp/GrocerApp/Assets/SmallLogo.png
new file mode 100644
index 0000000..1eb0d9d
Binary files /dev/null and b/Source Code/Chapter 2/GrocerApp/GrocerApp/Assets/SmallLogo.png differ
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/Assets/SplashScreen.png b/Source Code/Chapter 2/GrocerApp/GrocerApp/Assets/SplashScreen.png
new file mode 100644
index 0000000..c951e03
Binary files /dev/null and b/Source Code/Chapter 2/GrocerApp/GrocerApp/Assets/SplashScreen.png differ
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/Assets/StoreLogo.png b/Source Code/Chapter 2/GrocerApp/GrocerApp/Assets/StoreLogo.png
new file mode 100644
index 0000000..dcb6727
Binary files /dev/null and b/Source Code/Chapter 2/GrocerApp/GrocerApp/Assets/StoreLogo.png differ
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/Common/StandardStyles.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/Common/StandardStyles.xaml
new file mode 100644
index 0000000..85f4ed6
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/Common/StandardStyles.xaml
@@ -0,0 +1,1829 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mouse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/Data/GroceryItem.cs b/Source Code/Chapter 2/GrocerApp/GrocerApp/Data/GroceryItem.cs
new file mode 100644
index 0000000..1ab8849
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/Data/GroceryItem.cs
@@ -0,0 +1,31 @@
+using System.ComponentModel;
+
+namespace GrocerApp.Data {
+
+ class GroceryItem : INotifyPropertyChanged {
+ private string name, store;
+ private int quantity;
+
+ public string Name {
+ get { return name; }
+ set { name = value; NotifyPropertyChanged("Name"); }
+ }
+
+ public int Quantity {
+ get { return quantity; }
+ set { quantity = value; NotifyPropertyChanged("Quantity"); }
+ }
+
+ public string Store {
+ get { return store; }
+ set { store = value; NotifyPropertyChanged("Store"); }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ private void NotifyPropertyChanged(string propName) {
+ if (PropertyChanged != null) {
+ PropertyChanged(this, new PropertyChangedEventArgs(propName));
+ }
+ }
+ }
+}
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/Data/ViewModel.cs b/Source Code/Chapter 2/GrocerApp/GrocerApp/Data/ViewModel.cs
new file mode 100644
index 0000000..0fa3520
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/Data/ViewModel.cs
@@ -0,0 +1,52 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+
+namespace GrocerApp.Data {
+
+ class ViewModel : INotifyPropertyChanged {
+ private ObservableCollection groceryList;
+ private List storeList;
+ private int selectedItemIndex;
+ private string homeZipCode;
+
+ public ViewModel() {
+ groceryList = new ObservableCollection();
+ storeList = new List();
+ selectedItemIndex = -1;
+ homeZipCode = "NY 10118";
+ }
+
+ public string HomeZipCode {
+ get { return homeZipCode; }
+ set { homeZipCode = value; NotifyPropertyChanged("HomeZipCode"); }
+ }
+
+ public int SelectedItemIndex {
+ get { return selectedItemIndex; }
+ set {
+ selectedItemIndex = value; NotifyPropertyChanged("SelectedItemIndex");
+ }
+ }
+
+ public ObservableCollection GroceryList {
+ get {
+ return groceryList;
+ }
+ }
+
+ public List StoreList {
+ get {
+ return storeList;
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ private void NotifyPropertyChanged(string propName) {
+ if (PropertyChanged != null) {
+ PropertyChanged(this, new PropertyChangedEventArgs(propName));
+ }
+ }
+ }
+
+}
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/GrocerApp.csproj b/Source Code/Chapter 2/GrocerApp/GrocerApp/GrocerApp.csproj
new file mode 100644
index 0000000..bcbc870
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/GrocerApp.csproj
@@ -0,0 +1,172 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}
+ AppContainerExe
+ Properties
+ GrocerApp
+ GrocerApp
+ en-US
+ 512
+ {BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ GrocerApp_TemporaryKey.pfx
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE;NETFX_CORE
+ prompt
+ 4
+
+
+ true
+ bin\ARM\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ ARM
+ false
+ prompt
+ true
+
+
+ bin\ARM\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ ARM
+ false
+ prompt
+ true
+
+
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ x64
+ false
+ prompt
+ true
+
+
+ bin\x64\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ x64
+ false
+ prompt
+ true
+
+
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ x86
+ false
+ prompt
+ true
+
+
+ bin\x86\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ x86
+ false
+ prompt
+ true
+
+
+
+
+
+
+ App.xaml
+
+
+
+
+ ItemDetail.xaml
+
+
+ ListPage.xaml
+
+
+ NoItemSelected.xaml
+
+
+
+
+
+ Designer
+
+
+
+
+
+
+
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ PreserveNewest
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+ 11.0
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/GrocerApp.csproj.user b/Source Code/Chapter 2/GrocerApp/GrocerApp/GrocerApp.csproj.user
new file mode 100644
index 0000000..b29230c
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/GrocerApp.csproj.user
@@ -0,0 +1,6 @@
+
+
+
+ True
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/GrocerApp_TemporaryKey.pfx b/Source Code/Chapter 2/GrocerApp/GrocerApp/GrocerApp_TemporaryKey.pfx
new file mode 100644
index 0000000..27d6028
Binary files /dev/null and b/Source Code/Chapter 2/GrocerApp/GrocerApp/GrocerApp_TemporaryKey.pfx differ
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/Package.appxmanifest b/Source Code/Chapter 2/GrocerApp/GrocerApp/Package.appxmanifest
new file mode 100644
index 0000000..518710a
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/Package.appxmanifest
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+ GrocerApp
+ adam
+ Assets\StoreLogo.png
+
+
+
+ 6.2.1
+ 6.2.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/ItemDetail.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/ItemDetail.xaml
new file mode 100644
index 0000000..d5be62b
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/ItemDetail.xaml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/ItemDetail.xaml.cs b/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/ItemDetail.xaml.cs
new file mode 100644
index 0000000..00b0b90
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/ItemDetail.xaml.cs
@@ -0,0 +1,73 @@
+using GrocerApp.Data;
+using System;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Navigation;
+
+namespace GrocerApp.Pages {
+
+ public sealed partial class ItemDetail : Page {
+ private ViewModel viewModel;
+
+ public ItemDetail() {
+ this.InitializeComponent();
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+
+ viewModel = e.Parameter as ViewModel;
+ this.DataContext = viewModel;
+
+ viewModel.PropertyChanged += (sender, eventArgs) => {
+ if (eventArgs.PropertyName == "SelectedItemIndex") {
+ if (viewModel.SelectedItemIndex == -1) {
+ SetItemDetail(null);
+ } else {
+ SetItemDetail(viewModel.GroceryList
+ [viewModel.SelectedItemIndex]);
+ }
+ }
+ };
+ SetItemDetail(viewModel.GroceryList[viewModel.SelectedItemIndex]);
+ }
+
+ private void SetItemDetail(GroceryItem item) {
+ ItemDetailName.Text = (item == null) ? "" : item.Name;
+ ItemDetailQuantity.Text = (item == null) ? ""
+ : item.Quantity.ToString();
+
+ if (item != null) {
+ ItemDetailStore.SelectedItem = item.Store;
+ } else {
+ ItemDetailStore.SelectedIndex = -1;
+ }
+ }
+
+ private void HandleItemChange(object sender, RoutedEventArgs e) {
+ if (viewModel.SelectedItemIndex > -1) {
+
+ GroceryItem selectedItem = viewModel.GroceryList
+ [viewModel.SelectedItemIndex];
+
+ if (sender == ItemDetailName) {
+ selectedItem.Name = ItemDetailName.Text;
+
+ } else if (sender == ItemDetailQuantity) {
+ int intVal;
+ bool parsed = Int32.TryParse(ItemDetailQuantity.Text,
+ out intVal);
+ if (parsed) {
+ selectedItem.Quantity = intVal;
+ }
+ } else if (sender == ItemDetailStore) {
+ string store = (String)((ComboBox)sender).SelectedItem;
+
+ if (store != null) {
+ viewModel.GroceryList
+ [viewModel.SelectedItemIndex].Store = store;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/ListPage.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/ListPage.xaml
new file mode 100644
index 0000000..0b07b10
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/ListPage.xaml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/ListPage.xaml.cs b/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/ListPage.xaml.cs
new file mode 100644
index 0000000..a2a6e08
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/ListPage.xaml.cs
@@ -0,0 +1,62 @@
+using GrocerApp.Data;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Navigation;
+
+namespace GrocerApp.Pages {
+
+ public sealed partial class ListPage : Page {
+ ViewModel viewModel;
+
+
+ public ListPage() {
+
+ viewModel = new ViewModel();
+
+ viewModel.StoreList.Add("Whole Foods");
+ viewModel.StoreList.Add("Kroger");
+ viewModel.StoreList.Add("Costco");
+ viewModel.StoreList.Add("Walmart");
+
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Apples",
+ Quantity = 4, Store = "Whole Foods"
+ });
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Hotdogs",
+ Quantity = 12, Store = "Costco"
+ });
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Soda",
+ Quantity = 2, Store = "Costco"
+ });
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Eggs",
+ Quantity = 12, Store = "Kroger"
+ });
+
+
+ this.InitializeComponent();
+
+ this.DataContext = viewModel;
+
+ ItemDetailFrame.Navigate(typeof(NoItemSelected));
+
+ viewModel.PropertyChanged += (sender, args) => {
+ if (args.PropertyName == "SelectedItemIndex") {
+ if (viewModel.SelectedItemIndex == -1) {
+ ItemDetailFrame.Navigate(typeof(NoItemSelected));
+ } else {
+ ItemDetailFrame.Navigate(typeof(ItemDetail), viewModel);
+ }
+ }
+ };
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+ }
+
+ private void ListSelectionChanged(object sender, SelectionChangedEventArgs e) {
+ viewModel.SelectedItemIndex = groceryList.SelectedIndex;
+ }
+ }
+}
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml
new file mode 100644
index 0000000..484abad
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml.cs b/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml.cs
new file mode 100644
index 0000000..65510c8
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+using Windows.UI.Xaml.Data;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Navigation;
+
+// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
+
+namespace GrocerApp.Pages {
+ ///
+ /// An empty page that can be used on its own or navigated to within a Frame.
+ ///
+ public sealed partial class NoItemSelected : Page {
+ public NoItemSelected() {
+ this.InitializeComponent();
+ }
+
+ ///
+ /// Invoked when this page is about to be displayed in a Frame.
+ ///
+ /// Event data that describes how this page was reached. The Parameter
+ /// property is typically used to configure the page.
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+ }
+ }
+}
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/Properties/AssemblyInfo.cs b/Source Code/Chapter 2/GrocerApp/GrocerApp/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..f2e348e
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/Properties/AssemblyInfo.cs
@@ -0,0 +1,29 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GrocerApp")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("GrocerApp")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/Resources/GrocerResourceDictionary.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/Resources/GrocerResourceDictionary.xaml
new file mode 100644
index 0000000..19a1c3f
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/Resources/GrocerResourceDictionary.xaml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/App.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/App.xaml
new file mode 100644
index 0000000..ffa7458
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/App.xaml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/App.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/App.xaml
new file mode 100644
index 0000000..ffa7458
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/App.xaml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/AppxManifest.xml b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/AppxManifest.xml
new file mode 100644
index 0000000..1729ee4
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/AppxManifest.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+ GrocerApp
+ adam
+ Assets\StoreLogo.png
+
+
+ 6.2.1
+ 6.2.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Assets/Logo.png b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Assets/Logo.png
new file mode 100644
index 0000000..e26771c
Binary files /dev/null and b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Assets/Logo.png differ
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Assets/SmallLogo.png b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Assets/SmallLogo.png
new file mode 100644
index 0000000..1eb0d9d
Binary files /dev/null and b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Assets/SmallLogo.png differ
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Assets/SplashScreen.png b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Assets/SplashScreen.png
new file mode 100644
index 0000000..c951e03
Binary files /dev/null and b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Assets/SplashScreen.png differ
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Assets/StoreLogo.png b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Assets/StoreLogo.png
new file mode 100644
index 0000000..dcb6727
Binary files /dev/null and b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Assets/StoreLogo.png differ
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Common/StandardStyles.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Common/StandardStyles.xaml
new file mode 100644
index 0000000..ceec3df
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Common/StandardStyles.xaml
@@ -0,0 +1,1830 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mouse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/GrocerApp.exe b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/GrocerApp.exe
new file mode 100644
index 0000000..73201fd
Binary files /dev/null and b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/GrocerApp.exe differ
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/GrocerApp.pdb b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/GrocerApp.pdb
new file mode 100644
index 0000000..e442493
Binary files /dev/null and b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/GrocerApp.pdb differ
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Pages/ItemDetail.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Pages/ItemDetail.xaml
new file mode 100644
index 0000000..54e4e89
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Pages/ItemDetail.xaml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Pages/ListPage.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Pages/ListPage.xaml
new file mode 100644
index 0000000..1f07360
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Pages/ListPage.xaml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Pages/NoItemSelected.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Pages/NoItemSelected.xaml
new file mode 100644
index 0000000..d96fc1e
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Pages/NoItemSelected.xaml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Resources/GrocerResourceDictionary.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Resources/GrocerResourceDictionary.xaml
new file mode 100644
index 0000000..19329e7
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/Resources/GrocerResourceDictionary.xaml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/resources.pri b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/resources.pri
new file mode 100644
index 0000000..cb91b3e
Binary files /dev/null and b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/resources.pri differ
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/vs.appxrecipe b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/vs.appxrecipe
new file mode 100644
index 0000000..9e7b949
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppX/vs.appxrecipe
@@ -0,0 +1,82 @@
+
+
+
+ TINY
+ adam
+ Debug|AnyCPU
+ neutral
+ 54C69677BE5E223FF97137A042AC6839BFACD8A3E23204BDE309CE1FA84DDC06
+ a0873d78-0e13-4e25-93fa-58269cbe4e7f_1.0.0.0_neutral__6fxp0bkxjs8ye
+ a0873d78-0e13-4e25-93fa-58269cbe4e7f_6fxp0bkxjs8ye!App
+ a0873d78-0e13-4e25-93fa-58269cbe4e7f
+ CN=adam
+ 1.0.0.0
+
+
+
+ AppxManifest.xml
+ true
+ 2012-09-25T08:26:40.210
+
+
+
+
+ GrocerApp.exe
+ 2012-09-25T08:26:40.127
+
+
+ GrocerApp.pdb
+ 2012-09-25T08:26:40.114
+
+
+ Assets\Logo.png
+ true
+ 2012-03-15T19:42:52.000
+
+
+ Assets\SmallLogo.png
+ true
+ 2012-03-15T19:42:52.000
+
+
+ Assets\SplashScreen.png
+ true
+ 2012-03-15T19:42:52.000
+
+
+ Assets\StoreLogo.png
+ true
+ 2012-03-15T19:42:52.000
+
+
+ App.xaml
+ 2012-09-25T08:01:52.971
+
+
+ Pages\ItemDetail.xaml
+ 2012-09-25T08:22:30.499
+
+
+ Pages\NoItemSelected.xaml
+ 2012-09-25T08:14:13.969
+
+
+ Resources\GrocerResourceDictionary.xaml
+ 2012-09-25T08:21:37.869
+
+
+ Pages\ListPage.xaml
+ 2012-09-25T08:12:34.103
+
+
+ Common\StandardStyles.xaml
+ 2012-06-26T15:19:20.000
+
+
+ resources.pri
+ 2012-09-25T08:26:40.169
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppxManifest.xml b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppxManifest.xml
new file mode 100644
index 0000000..1729ee4
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/AppxManifest.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+ GrocerApp
+ adam
+ Assets\StoreLogo.png
+
+
+ 6.2.1
+ 6.2.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/Common/StandardStyles.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/Common/StandardStyles.xaml
new file mode 100644
index 0000000..ceec3df
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/Common/StandardStyles.xaml
@@ -0,0 +1,1830 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mouse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/GrocerApp.build.appxrecipe b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/GrocerApp.build.appxrecipe
new file mode 100644
index 0000000..3f60562
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/GrocerApp.build.appxrecipe
@@ -0,0 +1,62 @@
+
+
+
+ TINY
+ adam
+ Debug|AnyCPU
+ neutral
+
+
+
+ AppxManifest.xml
+ true
+
+
+
+
+ GrocerApp.exe
+
+
+ GrocerApp.pdb
+
+
+ Assets\Logo.png
+ true
+
+
+ Assets\SmallLogo.png
+ true
+
+
+ Assets\SplashScreen.png
+ true
+
+
+ Assets\StoreLogo.png
+ true
+
+
+ App.xaml
+
+
+ Pages\ItemDetail.xaml
+
+
+ Pages\NoItemSelected.xaml
+
+
+ Resources\GrocerResourceDictionary.xaml
+
+
+ Pages\ListPage.xaml
+
+
+ Common\StandardStyles.xaml
+
+
+ resources.pri
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/GrocerApp.exe b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/GrocerApp.exe
new file mode 100644
index 0000000..73201fd
Binary files /dev/null and b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/GrocerApp.exe differ
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/GrocerApp.pdb b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/GrocerApp.pdb
new file mode 100644
index 0000000..e442493
Binary files /dev/null and b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/GrocerApp.pdb differ
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/MainPage.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/MainPage.xaml
new file mode 100644
index 0000000..4fe838c
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/MainPage.xaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/Pages/ItemDetail.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/Pages/ItemDetail.xaml
new file mode 100644
index 0000000..54e4e89
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/Pages/ItemDetail.xaml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/Pages/ListPage.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/Pages/ListPage.xaml
new file mode 100644
index 0000000..1f07360
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/Pages/ListPage.xaml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/Pages/NoItemSelected.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/Pages/NoItemSelected.xaml
new file mode 100644
index 0000000..d96fc1e
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/Pages/NoItemSelected.xaml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/Resources/GrocerResourceDictionary.xaml b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/Resources/GrocerResourceDictionary.xaml
new file mode 100644
index 0000000..19329e7
--- /dev/null
+++ b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/Resources/GrocerResourceDictionary.xaml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/resources.pri b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/resources.pri
new file mode 100644
index 0000000..cb91b3e
Binary files /dev/null and b/Source Code/Chapter 2/GrocerApp/GrocerApp/bin/Debug/resources.pri differ
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp.sln b/Source Code/Chapter 3/GrocerApp/GrocerApp.sln
new file mode 100644
index 0000000..9185511
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp.sln
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 2012 for Windows 8
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrocerApp", "GrocerApp\GrocerApp.csproj", "{2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|ARM = Debug|ARM
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|ARM = Release|ARM
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|ARM.ActiveCfg = Debug|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|ARM.Build.0 = Debug|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|ARM.Deploy.0 = Debug|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x64.ActiveCfg = Debug|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x64.Build.0 = Debug|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x64.Deploy.0 = Debug|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x86.ActiveCfg = Debug|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x86.Build.0 = Debug|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x86.Deploy.0 = Debug|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|ARM.ActiveCfg = Release|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|ARM.Build.0 = Release|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|ARM.Deploy.0 = Release|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x64.ActiveCfg = Release|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x64.Build.0 = Release|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x64.Deploy.0 = Release|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x86.ActiveCfg = Release|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x86.Build.0 = Release|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x86.Deploy.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp.v11.suo b/Source Code/Chapter 3/GrocerApp/GrocerApp.v11.suo
new file mode 100644
index 0000000..0e6c536
Binary files /dev/null and b/Source Code/Chapter 3/GrocerApp/GrocerApp.v11.suo differ
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/App.xaml b/Source Code/Chapter 3/GrocerApp/GrocerApp/App.xaml
new file mode 100644
index 0000000..fc45fa5
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/App.xaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/App.xaml.cs b/Source Code/Chapter 3/GrocerApp/GrocerApp/App.xaml.cs
new file mode 100644
index 0000000..362baf2
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/App.xaml.cs
@@ -0,0 +1,48 @@
+using System;
+using Windows.ApplicationModel;
+using Windows.ApplicationModel.Activation;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace GrocerApp {
+
+ sealed partial class App : Application {
+
+ public App() {
+ this.InitializeComponent();
+ this.Suspending += OnSuspending;
+ }
+
+ protected override void OnLaunched(LaunchActivatedEventArgs args) {
+ Frame rootFrame = Window.Current.Content as Frame;
+
+
+ if (rootFrame == null) {
+ // Create a Frame to act as the navigation context and navigate to the first page
+ rootFrame = new Frame();
+
+ if (args.PreviousExecutionState == ApplicationExecutionState.Terminated) {
+ //TODO: Load state from previously suspended application
+ }
+
+ // Place the frame in the current Window
+ Window.Current.Content = rootFrame;
+ }
+
+if (rootFrame.Content == null) {
+
+ if (!rootFrame.Navigate(typeof(Pages.MainPage), args.Arguments)) {
+ throw new Exception("Failed to create initial page");
+ }
+}
+ // Ensure the current window is active
+ Window.Current.Activate();
+ }
+
+ private void OnSuspending(object sender, SuspendingEventArgs e) {
+ var deferral = e.SuspendingOperation.GetDeferral();
+ //TODO: Save application state and stop any background activity
+ deferral.Complete();
+ }
+ }
+}
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Assets/Logo.png b/Source Code/Chapter 3/GrocerApp/GrocerApp/Assets/Logo.png
new file mode 100644
index 0000000..e26771c
Binary files /dev/null and b/Source Code/Chapter 3/GrocerApp/GrocerApp/Assets/Logo.png differ
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Assets/SmallLogo.png b/Source Code/Chapter 3/GrocerApp/GrocerApp/Assets/SmallLogo.png
new file mode 100644
index 0000000..1eb0d9d
Binary files /dev/null and b/Source Code/Chapter 3/GrocerApp/GrocerApp/Assets/SmallLogo.png differ
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Assets/SplashScreen.png b/Source Code/Chapter 3/GrocerApp/GrocerApp/Assets/SplashScreen.png
new file mode 100644
index 0000000..c951e03
Binary files /dev/null and b/Source Code/Chapter 3/GrocerApp/GrocerApp/Assets/SplashScreen.png differ
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Assets/StoreLogo.png b/Source Code/Chapter 3/GrocerApp/GrocerApp/Assets/StoreLogo.png
new file mode 100644
index 0000000..dcb6727
Binary files /dev/null and b/Source Code/Chapter 3/GrocerApp/GrocerApp/Assets/StoreLogo.png differ
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Assets/Thumbs.db b/Source Code/Chapter 3/GrocerApp/GrocerApp/Assets/Thumbs.db
new file mode 100644
index 0000000..c29a157
Binary files /dev/null and b/Source Code/Chapter 3/GrocerApp/GrocerApp/Assets/Thumbs.db differ
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Common/StandardStyles.xaml b/Source Code/Chapter 3/GrocerApp/GrocerApp/Common/StandardStyles.xaml
new file mode 100644
index 0000000..1afaf54
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Common/StandardStyles.xaml
@@ -0,0 +1,1837 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mouse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Data/GroceryItem.cs b/Source Code/Chapter 3/GrocerApp/GrocerApp/Data/GroceryItem.cs
new file mode 100644
index 0000000..1ab8849
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Data/GroceryItem.cs
@@ -0,0 +1,31 @@
+using System.ComponentModel;
+
+namespace GrocerApp.Data {
+
+ class GroceryItem : INotifyPropertyChanged {
+ private string name, store;
+ private int quantity;
+
+ public string Name {
+ get { return name; }
+ set { name = value; NotifyPropertyChanged("Name"); }
+ }
+
+ public int Quantity {
+ get { return quantity; }
+ set { quantity = value; NotifyPropertyChanged("Quantity"); }
+ }
+
+ public string Store {
+ get { return store; }
+ set { store = value; NotifyPropertyChanged("Store"); }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ private void NotifyPropertyChanged(string propName) {
+ if (PropertyChanged != null) {
+ PropertyChanged(this, new PropertyChangedEventArgs(propName));
+ }
+ }
+ }
+}
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Data/ViewModel.cs b/Source Code/Chapter 3/GrocerApp/GrocerApp/Data/ViewModel.cs
new file mode 100644
index 0000000..0fa3520
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Data/ViewModel.cs
@@ -0,0 +1,52 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+
+namespace GrocerApp.Data {
+
+ class ViewModel : INotifyPropertyChanged {
+ private ObservableCollection groceryList;
+ private List storeList;
+ private int selectedItemIndex;
+ private string homeZipCode;
+
+ public ViewModel() {
+ groceryList = new ObservableCollection();
+ storeList = new List();
+ selectedItemIndex = -1;
+ homeZipCode = "NY 10118";
+ }
+
+ public string HomeZipCode {
+ get { return homeZipCode; }
+ set { homeZipCode = value; NotifyPropertyChanged("HomeZipCode"); }
+ }
+
+ public int SelectedItemIndex {
+ get { return selectedItemIndex; }
+ set {
+ selectedItemIndex = value; NotifyPropertyChanged("SelectedItemIndex");
+ }
+ }
+
+ public ObservableCollection GroceryList {
+ get {
+ return groceryList;
+ }
+ }
+
+ public List StoreList {
+ get {
+ return storeList;
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ private void NotifyPropertyChanged(string propName) {
+ if (PropertyChanged != null) {
+ PropertyChanged(this, new PropertyChangedEventArgs(propName));
+ }
+ }
+ }
+
+}
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml b/Source Code/Chapter 3/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml
new file mode 100644
index 0000000..b4d917e
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml.cs b/Source Code/Chapter 3/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml.cs
new file mode 100644
index 0000000..ed84b26
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml.cs
@@ -0,0 +1,29 @@
+using System;
+using GrocerApp.Data;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace GrocerApp.Flyouts {
+ public sealed partial class AddItemFlyout : UserControl {
+
+ public AddItemFlyout() {
+ this.InitializeComponent();
+ }
+
+ public void Show(Page page, AppBar appbar, Button button) {
+ AddItemPopup.IsOpen = true;
+ FlyoutHelper.ShowRelativeToAppBar(AddItemPopup, page, appbar, button);
+ }
+
+ private void AddButtonClick(object sender, RoutedEventArgs e) {
+
+ ((ViewModel)DataContext).GroceryList.Add(new GroceryItem {
+ Name = ItemName.Text,
+ Quantity = Int32.Parse(ItemQuantity.Text),
+ Store = ItemStore.SelectedItem.ToString()
+ });
+
+ AddItemPopup.IsOpen = false;
+ }
+ }
+}
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Flyouts/FlyoutHelper.cs b/Source Code/Chapter 3/GrocerApp/GrocerApp/Flyouts/FlyoutHelper.cs
new file mode 100644
index 0000000..23de22a
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Flyouts/FlyoutHelper.cs
@@ -0,0 +1,38 @@
+using System;
+using Windows.Foundation;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+
+namespace GrocerApp.Flyouts {
+ class FlyoutHelper {
+
+ public static void ShowRelativeToAppBar(Popup popup, Page page,
+ AppBar appbar, Button button) {
+
+ Func getOffset =
+ delegate(UIElement control1, UIElement control2) {
+ return control1.TransformToVisual(control2)
+ .TransformPoint(new Point(0, 0));
+ };
+
+ Point popupOffset = getOffset(popup, page);
+
+ Point buttonOffset = getOffset(button, page);
+ popup.HorizontalOffset = buttonOffset.X - popupOffset.X
+ - (popup.ActualWidth / 2) + (button.ActualWidth / 2);
+ popup.VerticalOffset = getOffset(appbar, page).Y
+ - popupOffset.Y - popup.ActualHeight;
+
+ if (popupOffset.X + popup.HorizontalOffset
+ + popup.ActualWidth > page.ActualWidth) {
+
+ popup.HorizontalOffset = page.ActualWidth
+ - popupOffset.X - popup.ActualWidth;
+ } else if (popup.HorizontalOffset + popupOffset.X < 0) {
+ popup.HorizontalOffset = -popupOffset.X;
+ }
+ }
+
+ }
+}
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml b/Source Code/Chapter 3/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml
new file mode 100644
index 0000000..7edbf11
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml.cs b/Source Code/Chapter 3/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml.cs
new file mode 100644
index 0000000..081555e
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml.cs
@@ -0,0 +1,20 @@
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace GrocerApp.Flyouts {
+ public sealed partial class HomeZipCodeFlyout : UserControl {
+
+ public HomeZipCodeFlyout() {
+ this.InitializeComponent();
+ }
+
+ public void Show(Page page, AppBar appbar, Button button) {
+ HomeZipCodePopup.IsOpen = true;
+ FlyoutHelper.ShowRelativeToAppBar(HomeZipCodePopup, page, appbar, button);
+ }
+
+ private void OKButtonClick(object sender, RoutedEventArgs e) {
+ HomeZipCodePopup.IsOpen = false;
+ }
+ }
+}
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/GrocerApp.csproj b/Source Code/Chapter 3/GrocerApp/GrocerApp/GrocerApp.csproj
new file mode 100644
index 0000000..cb089b7
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/GrocerApp.csproj
@@ -0,0 +1,201 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}
+ AppContainerExe
+ Properties
+ GrocerApp
+ GrocerApp
+ en-US
+ 512
+ {BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ GrocerApp_TemporaryKey.pfx
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE;NETFX_CORE
+ prompt
+ 4
+
+
+ true
+ bin\ARM\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ ARM
+ false
+ prompt
+ true
+
+
+ bin\ARM\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ ARM
+ false
+ prompt
+ true
+
+
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ x64
+ false
+ prompt
+ true
+
+
+ bin\x64\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ x64
+ false
+ prompt
+ true
+
+
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ x86
+ false
+ prompt
+ true
+
+
+ bin\x86\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ x86
+ false
+ prompt
+ true
+
+
+
+
+
+
+ App.xaml
+
+
+
+
+ AddItemFlyout.xaml
+
+
+
+ HomeZipCodeFlyout.xaml
+
+
+ DetailPage.xaml
+
+
+ ItemDetail.xaml
+
+
+ ListPage.xaml
+
+
+ MainPage.xaml
+
+
+ NoItemSelected.xaml
+
+
+
+
+
+ Designer
+
+
+
+
+
+
+
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ PreserveNewest
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+ 11.0
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/GrocerApp.csproj.user b/Source Code/Chapter 3/GrocerApp/GrocerApp/GrocerApp.csproj.user
new file mode 100644
index 0000000..b29230c
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/GrocerApp.csproj.user
@@ -0,0 +1,6 @@
+
+
+
+ True
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/GrocerApp_TemporaryKey.pfx b/Source Code/Chapter 3/GrocerApp/GrocerApp/GrocerApp_TemporaryKey.pfx
new file mode 100644
index 0000000..27d6028
Binary files /dev/null and b/Source Code/Chapter 3/GrocerApp/GrocerApp/GrocerApp_TemporaryKey.pfx differ
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Package.appxmanifest b/Source Code/Chapter 3/GrocerApp/GrocerApp/Package.appxmanifest
new file mode 100644
index 0000000..518710a
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Package.appxmanifest
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+ GrocerApp
+ adam
+ Assets\StoreLogo.png
+
+
+
+ 6.2.1
+ 6.2.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/DetailPage.xaml b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/DetailPage.xaml
new file mode 100644
index 0000000..0d198dc
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/DetailPage.xaml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/DetailPage.xaml.cs b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/DetailPage.xaml.cs
new file mode 100644
index 0000000..34d714a
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/DetailPage.xaml.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+using Windows.UI.Xaml.Data;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Navigation;
+
+// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
+
+namespace GrocerApp.Pages {
+ ///
+ /// An empty page that can be used on its own or navigated to within a Frame.
+ ///
+ public sealed partial class DetailPage : Page {
+ public DetailPage() {
+ this.InitializeComponent();
+ }
+
+ ///
+ /// Invoked when this page is about to be displayed in a Frame.
+ ///
+ /// Event data that describes how this page was reached. The Parameter
+ /// property is typically used to configure the page.
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+ }
+ }
+}
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/ItemDetail.xaml b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/ItemDetail.xaml
new file mode 100644
index 0000000..d5be62b
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/ItemDetail.xaml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/ItemDetail.xaml.cs b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/ItemDetail.xaml.cs
new file mode 100644
index 0000000..00b0b90
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/ItemDetail.xaml.cs
@@ -0,0 +1,73 @@
+using GrocerApp.Data;
+using System;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Navigation;
+
+namespace GrocerApp.Pages {
+
+ public sealed partial class ItemDetail : Page {
+ private ViewModel viewModel;
+
+ public ItemDetail() {
+ this.InitializeComponent();
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+
+ viewModel = e.Parameter as ViewModel;
+ this.DataContext = viewModel;
+
+ viewModel.PropertyChanged += (sender, eventArgs) => {
+ if (eventArgs.PropertyName == "SelectedItemIndex") {
+ if (viewModel.SelectedItemIndex == -1) {
+ SetItemDetail(null);
+ } else {
+ SetItemDetail(viewModel.GroceryList
+ [viewModel.SelectedItemIndex]);
+ }
+ }
+ };
+ SetItemDetail(viewModel.GroceryList[viewModel.SelectedItemIndex]);
+ }
+
+ private void SetItemDetail(GroceryItem item) {
+ ItemDetailName.Text = (item == null) ? "" : item.Name;
+ ItemDetailQuantity.Text = (item == null) ? ""
+ : item.Quantity.ToString();
+
+ if (item != null) {
+ ItemDetailStore.SelectedItem = item.Store;
+ } else {
+ ItemDetailStore.SelectedIndex = -1;
+ }
+ }
+
+ private void HandleItemChange(object sender, RoutedEventArgs e) {
+ if (viewModel.SelectedItemIndex > -1) {
+
+ GroceryItem selectedItem = viewModel.GroceryList
+ [viewModel.SelectedItemIndex];
+
+ if (sender == ItemDetailName) {
+ selectedItem.Name = ItemDetailName.Text;
+
+ } else if (sender == ItemDetailQuantity) {
+ int intVal;
+ bool parsed = Int32.TryParse(ItemDetailQuantity.Text,
+ out intVal);
+ if (parsed) {
+ selectedItem.Quantity = intVal;
+ }
+ } else if (sender == ItemDetailStore) {
+ string store = (String)((ComboBox)sender).SelectedItem;
+
+ if (store != null) {
+ viewModel.GroceryList
+ [viewModel.SelectedItemIndex].Store = store;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/ListPage.xaml b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/ListPage.xaml
new file mode 100644
index 0000000..b40d7c1
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/ListPage.xaml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/ListPage.xaml.cs b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/ListPage.xaml.cs
new file mode 100644
index 0000000..b2ffd4a
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/ListPage.xaml.cs
@@ -0,0 +1,80 @@
+using GrocerApp.Data;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Navigation;
+
+namespace GrocerApp.Pages {
+
+ public sealed partial class ListPage : Page {
+ ViewModel viewModel;
+
+
+ public ListPage() {
+
+ viewModel = new ViewModel();
+
+ viewModel.StoreList.Add("Whole Foods");
+ viewModel.StoreList.Add("Kroger");
+ viewModel.StoreList.Add("Costco");
+ viewModel.StoreList.Add("Walmart");
+
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Apples",
+ Quantity = 4, Store = "Whole Foods"
+ });
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Hotdogs",
+ Quantity = 12, Store = "Costco"
+ });
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Soda",
+ Quantity = 2, Store = "Costco"
+ });
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Eggs",
+ Quantity = 12, Store = "Kroger"
+ });
+
+
+ this.InitializeComponent();
+
+ this.DataContext = viewModel;
+
+ ItemDetailFrame.Navigate(typeof(NoItemSelected));
+
+ viewModel.PropertyChanged += (sender, args) => {
+ if (args.PropertyName == "SelectedItemIndex") {
+ if (viewModel.SelectedItemIndex == -1) {
+ ItemDetailFrame.Navigate(typeof(NoItemSelected));
+ AppBarDoneButton.IsEnabled = false;
+ } else {
+ ItemDetailFrame.Navigate(typeof(ItemDetail), viewModel);
+ AppBarDoneButton.IsEnabled = true;
+ }
+ }
+ };
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+ }
+
+ private void ListSelectionChanged(object sender, SelectionChangedEventArgs e) {
+ viewModel.SelectedItemIndex = groceryList.SelectedIndex;
+ }
+
+ private void AppBarButtonClick(object sender, RoutedEventArgs e) {
+ if (e.OriginalSource == AppBarDoneButton
+ && viewModel.SelectedItemIndex > -1) {
+
+ viewModel.GroceryList.RemoveAt(viewModel.SelectedItemIndex);
+ viewModel.SelectedItemIndex = -1;
+
+ } else if (e.OriginalSource == AppBarZipButton) {
+ HomeZipFlyout.Show(this, this.BottomAppBar, (Button)e.OriginalSource);
+ } else if (e.OriginalSource == AppBarAddButton) {
+ AddItemFlyout.Show(this, this.BottomAppBar, (Button)e.OriginalSource);
+ }
+
+ }
+ }
+}
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/MainPage.xaml b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/MainPage.xaml
new file mode 100644
index 0000000..9d3d3ef
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/MainPage.xaml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/MainPage.xaml.cs b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/MainPage.xaml.cs
new file mode 100644
index 0000000..6004b0e
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/MainPage.xaml.cs
@@ -0,0 +1,55 @@
+using System;
+using GrocerApp.Data;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+using Windows.UI.Xaml.Navigation;
+
+namespace GrocerApp.Pages {
+
+ public sealed partial class MainPage : Page {
+ private ViewModel viewModel;
+
+ public MainPage() {
+ this.InitializeComponent();
+
+ viewModel = new ViewModel();
+
+ viewModel.StoreList.Add("Whole Foods");
+ viewModel.StoreList.Add("Kroger");
+ viewModel.StoreList.Add("Costco");
+ viewModel.StoreList.Add("Walmart");
+
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Apples",
+ Quantity = 4, Store = "Whole Foods"
+ });
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Hotdogs",
+ Quantity = 12, Store = "Costco"
+ });
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Soda",
+ Quantity = 2, Store = "Costco"
+ });
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Eggs",
+ Quantity = 12, Store = "Kroger"
+ });
+
+ this.DataContext = viewModel;
+
+ MainFrame.Navigate(typeof(ListPage), viewModel);
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+ }
+
+ private void NavBarButtonPress(object sender, RoutedEventArgs e) {
+ Boolean isListView = (Button)sender == ListViewButton;
+ MainFrame.Navigate(isListView ? typeof(ListPage)
+ : typeof(DetailPage), viewModel);
+
+ }
+ }
+}
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml
new file mode 100644
index 0000000..484abad
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml.cs b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml.cs
new file mode 100644
index 0000000..65510c8
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+using Windows.UI.Xaml.Data;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Navigation;
+
+// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
+
+namespace GrocerApp.Pages {
+ ///
+ /// An empty page that can be used on its own or navigated to within a Frame.
+ ///
+ public sealed partial class NoItemSelected : Page {
+ public NoItemSelected() {
+ this.InitializeComponent();
+ }
+
+ ///
+ /// Invoked when this page is about to be displayed in a Frame.
+ ///
+ /// Event data that describes how this page was reached. The Parameter
+ /// property is typically used to configure the page.
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+ }
+ }
+}
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Properties/AssemblyInfo.cs b/Source Code/Chapter 3/GrocerApp/GrocerApp/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..f2e348e
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Properties/AssemblyInfo.cs
@@ -0,0 +1,29 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GrocerApp")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("GrocerApp")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/Source Code/Chapter 3/GrocerApp/GrocerApp/Resources/GrocerResourceDictionary.xaml b/Source Code/Chapter 3/GrocerApp/GrocerApp/Resources/GrocerResourceDictionary.xaml
new file mode 100644
index 0000000..8975687
--- /dev/null
+++ b/Source Code/Chapter 3/GrocerApp/GrocerApp/Resources/GrocerResourceDictionary.xaml
@@ -0,0 +1,214 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp.sln b/Source Code/Chapter 4/GrocerApp/GrocerApp.sln
new file mode 100644
index 0000000..9185511
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp.sln
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 2012 for Windows 8
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrocerApp", "GrocerApp\GrocerApp.csproj", "{2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|ARM = Debug|ARM
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|ARM = Release|ARM
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|ARM.ActiveCfg = Debug|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|ARM.Build.0 = Debug|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|ARM.Deploy.0 = Debug|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x64.ActiveCfg = Debug|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x64.Build.0 = Debug|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x64.Deploy.0 = Debug|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x86.ActiveCfg = Debug|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x86.Build.0 = Debug|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x86.Deploy.0 = Debug|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|ARM.ActiveCfg = Release|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|ARM.Build.0 = Release|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|ARM.Deploy.0 = Release|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x64.ActiveCfg = Release|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x64.Build.0 = Release|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x64.Deploy.0 = Release|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x86.ActiveCfg = Release|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x86.Build.0 = Release|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x86.Deploy.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp.v11.suo b/Source Code/Chapter 4/GrocerApp/GrocerApp.v11.suo
new file mode 100644
index 0000000..0686d53
Binary files /dev/null and b/Source Code/Chapter 4/GrocerApp/GrocerApp.v11.suo differ
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/App.xaml b/Source Code/Chapter 4/GrocerApp/GrocerApp/App.xaml
new file mode 100644
index 0000000..fc45fa5
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/App.xaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/App.xaml.cs b/Source Code/Chapter 4/GrocerApp/GrocerApp/App.xaml.cs
new file mode 100644
index 0000000..362baf2
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/App.xaml.cs
@@ -0,0 +1,48 @@
+using System;
+using Windows.ApplicationModel;
+using Windows.ApplicationModel.Activation;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace GrocerApp {
+
+ sealed partial class App : Application {
+
+ public App() {
+ this.InitializeComponent();
+ this.Suspending += OnSuspending;
+ }
+
+ protected override void OnLaunched(LaunchActivatedEventArgs args) {
+ Frame rootFrame = Window.Current.Content as Frame;
+
+
+ if (rootFrame == null) {
+ // Create a Frame to act as the navigation context and navigate to the first page
+ rootFrame = new Frame();
+
+ if (args.PreviousExecutionState == ApplicationExecutionState.Terminated) {
+ //TODO: Load state from previously suspended application
+ }
+
+ // Place the frame in the current Window
+ Window.Current.Content = rootFrame;
+ }
+
+if (rootFrame.Content == null) {
+
+ if (!rootFrame.Navigate(typeof(Pages.MainPage), args.Arguments)) {
+ throw new Exception("Failed to create initial page");
+ }
+}
+ // Ensure the current window is active
+ Window.Current.Activate();
+ }
+
+ private void OnSuspending(object sender, SuspendingEventArgs e) {
+ var deferral = e.SuspendingOperation.GetDeferral();
+ //TODO: Save application state and stop any background activity
+ deferral.Complete();
+ }
+ }
+}
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/Logo.png b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/Logo.png
new file mode 100644
index 0000000..e26771c
Binary files /dev/null and b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/Logo.png differ
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/SmallLogo.png b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/SmallLogo.png
new file mode 100644
index 0000000..1eb0d9d
Binary files /dev/null and b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/SmallLogo.png differ
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/SplashScreen.png b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/SplashScreen.png
new file mode 100644
index 0000000..c951e03
Binary files /dev/null and b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/SplashScreen.png differ
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/StoreLogo.png b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/StoreLogo.png
new file mode 100644
index 0000000..dcb6727
Binary files /dev/null and b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/StoreLogo.png differ
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/Thumbs.db b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/Thumbs.db
new file mode 100644
index 0000000..46d617a
Binary files /dev/null and b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/Thumbs.db differ
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/tile150.png b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/tile150.png
new file mode 100644
index 0000000..bcc4f79
Binary files /dev/null and b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/tile150.png differ
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/tile30.png b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/tile30.png
new file mode 100644
index 0000000..bcc4e65
Binary files /dev/null and b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/tile30.png differ
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/tile310.png b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/tile310.png
new file mode 100644
index 0000000..e5f26ad
Binary files /dev/null and b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/tile310.png differ
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/tile620.png b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/tile620.png
new file mode 100644
index 0000000..c8e2fb9
Binary files /dev/null and b/Source Code/Chapter 4/GrocerApp/GrocerApp/Assets/tile620.png differ
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Common/StandardStyles.xaml b/Source Code/Chapter 4/GrocerApp/GrocerApp/Common/StandardStyles.xaml
new file mode 100644
index 0000000..1afaf54
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Common/StandardStyles.xaml
@@ -0,0 +1,1837 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mouse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Data/GroceryItem.cs b/Source Code/Chapter 4/GrocerApp/GrocerApp/Data/GroceryItem.cs
new file mode 100644
index 0000000..092be51
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Data/GroceryItem.cs
@@ -0,0 +1,31 @@
+using System.ComponentModel;
+
+namespace GrocerApp.Data {
+
+ public class GroceryItem : INotifyPropertyChanged {
+ private string name, store;
+ private int quantity;
+
+ public string Name {
+ get { return name; }
+ set { name = value; NotifyPropertyChanged("Name"); }
+ }
+
+ public int Quantity {
+ get { return quantity; }
+ set { quantity = value; NotifyPropertyChanged("Quantity"); }
+ }
+
+ public string Store {
+ get { return store; }
+ set { store = value; NotifyPropertyChanged("Store"); }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ private void NotifyPropertyChanged(string propName) {
+ if (PropertyChanged != null) {
+ PropertyChanged(this, new PropertyChangedEventArgs(propName));
+ }
+ }
+ }
+}
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Data/ViewModel.cs b/Source Code/Chapter 4/GrocerApp/GrocerApp/Data/ViewModel.cs
new file mode 100644
index 0000000..8c90a56
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Data/ViewModel.cs
@@ -0,0 +1,52 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+
+namespace GrocerApp.Data {
+
+ public class ViewModel : INotifyPropertyChanged {
+ private ObservableCollection groceryList;
+ private List storeList;
+ private int selectedItemIndex;
+ private string homeZipCode;
+
+ public ViewModel() {
+ groceryList = new ObservableCollection();
+ storeList = new List();
+ selectedItemIndex = -1;
+ homeZipCode = "NY 10118";
+ }
+
+ public string HomeZipCode {
+ get { return homeZipCode; }
+ set { homeZipCode = value; NotifyPropertyChanged("HomeZipCode"); }
+ }
+
+ public int SelectedItemIndex {
+ get { return selectedItemIndex; }
+ set {
+ selectedItemIndex = value; NotifyPropertyChanged("SelectedItemIndex");
+ }
+ }
+
+ public ObservableCollection GroceryList {
+ get {
+ return groceryList;
+ }
+ }
+
+ public List StoreList {
+ get {
+ return storeList;
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ private void NotifyPropertyChanged(string propName) {
+ if (PropertyChanged != null) {
+ PropertyChanged(this, new PropertyChangedEventArgs(propName));
+ }
+ }
+ }
+
+}
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml b/Source Code/Chapter 4/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml
new file mode 100644
index 0000000..b4d917e
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml.cs b/Source Code/Chapter 4/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml.cs
new file mode 100644
index 0000000..ed84b26
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml.cs
@@ -0,0 +1,29 @@
+using System;
+using GrocerApp.Data;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace GrocerApp.Flyouts {
+ public sealed partial class AddItemFlyout : UserControl {
+
+ public AddItemFlyout() {
+ this.InitializeComponent();
+ }
+
+ public void Show(Page page, AppBar appbar, Button button) {
+ AddItemPopup.IsOpen = true;
+ FlyoutHelper.ShowRelativeToAppBar(AddItemPopup, page, appbar, button);
+ }
+
+ private void AddButtonClick(object sender, RoutedEventArgs e) {
+
+ ((ViewModel)DataContext).GroceryList.Add(new GroceryItem {
+ Name = ItemName.Text,
+ Quantity = Int32.Parse(ItemQuantity.Text),
+ Store = ItemStore.SelectedItem.ToString()
+ });
+
+ AddItemPopup.IsOpen = false;
+ }
+ }
+}
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Flyouts/FlyoutHelper.cs b/Source Code/Chapter 4/GrocerApp/GrocerApp/Flyouts/FlyoutHelper.cs
new file mode 100644
index 0000000..23de22a
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Flyouts/FlyoutHelper.cs
@@ -0,0 +1,38 @@
+using System;
+using Windows.Foundation;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+
+namespace GrocerApp.Flyouts {
+ class FlyoutHelper {
+
+ public static void ShowRelativeToAppBar(Popup popup, Page page,
+ AppBar appbar, Button button) {
+
+ Func getOffset =
+ delegate(UIElement control1, UIElement control2) {
+ return control1.TransformToVisual(control2)
+ .TransformPoint(new Point(0, 0));
+ };
+
+ Point popupOffset = getOffset(popup, page);
+
+ Point buttonOffset = getOffset(button, page);
+ popup.HorizontalOffset = buttonOffset.X - popupOffset.X
+ - (popup.ActualWidth / 2) + (button.ActualWidth / 2);
+ popup.VerticalOffset = getOffset(appbar, page).Y
+ - popupOffset.Y - popup.ActualHeight;
+
+ if (popupOffset.X + popup.HorizontalOffset
+ + popup.ActualWidth > page.ActualWidth) {
+
+ popup.HorizontalOffset = page.ActualWidth
+ - popupOffset.X - popup.ActualWidth;
+ } else if (popup.HorizontalOffset + popupOffset.X < 0) {
+ popup.HorizontalOffset = -popupOffset.X;
+ }
+ }
+
+ }
+}
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml b/Source Code/Chapter 4/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml
new file mode 100644
index 0000000..7edbf11
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml.cs b/Source Code/Chapter 4/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml.cs
new file mode 100644
index 0000000..081555e
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml.cs
@@ -0,0 +1,20 @@
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace GrocerApp.Flyouts {
+ public sealed partial class HomeZipCodeFlyout : UserControl {
+
+ public HomeZipCodeFlyout() {
+ this.InitializeComponent();
+ }
+
+ public void Show(Page page, AppBar appbar, Button button) {
+ HomeZipCodePopup.IsOpen = true;
+ FlyoutHelper.ShowRelativeToAppBar(HomeZipCodePopup, page, appbar, button);
+ }
+
+ private void OKButtonClick(object sender, RoutedEventArgs e) {
+ HomeZipCodePopup.IsOpen = false;
+ }
+ }
+}
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/GrocerApp.csproj b/Source Code/Chapter 4/GrocerApp/GrocerApp/GrocerApp.csproj
new file mode 100644
index 0000000..f0b617f
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/GrocerApp.csproj
@@ -0,0 +1,205 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}
+ AppContainerExe
+ Properties
+ GrocerApp
+ GrocerApp
+ en-US
+ 512
+ {BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ GrocerApp_TemporaryKey.pfx
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE;NETFX_CORE
+ prompt
+ 4
+
+
+ true
+ bin\ARM\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ ARM
+ false
+ prompt
+ true
+
+
+ bin\ARM\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ ARM
+ false
+ prompt
+ true
+
+
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ x64
+ false
+ prompt
+ true
+
+
+ bin\x64\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ x64
+ false
+ prompt
+ true
+
+
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ x86
+ false
+ prompt
+ true
+
+
+ bin\x86\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ x86
+ false
+ prompt
+ true
+
+
+
+
+
+
+ App.xaml
+
+
+
+
+ AddItemFlyout.xaml
+
+
+
+ HomeZipCodeFlyout.xaml
+
+
+ DetailPage.xaml
+
+
+ ItemDetail.xaml
+
+
+ ListPage.xaml
+
+
+ MainPage.xaml
+
+
+ NoItemSelected.xaml
+
+
+
+
+
+ Designer
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ PreserveNewest
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+ 11.0
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/GrocerApp.csproj.user b/Source Code/Chapter 4/GrocerApp/GrocerApp/GrocerApp.csproj.user
new file mode 100644
index 0000000..e98010e
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/GrocerApp.csproj.user
@@ -0,0 +1,6 @@
+
+
+
+ False
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/GrocerApp_TemporaryKey.pfx b/Source Code/Chapter 4/GrocerApp/GrocerApp/GrocerApp_TemporaryKey.pfx
new file mode 100644
index 0000000..27d6028
Binary files /dev/null and b/Source Code/Chapter 4/GrocerApp/GrocerApp/GrocerApp_TemporaryKey.pfx differ
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Package.appxmanifest b/Source Code/Chapter 4/GrocerApp/GrocerApp/Package.appxmanifest
new file mode 100644
index 0000000..a32e8bf
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Package.appxmanifest
@@ -0,0 +1,27 @@
+
+
+
+
+ GrocerApp
+ adam
+ Assets\StoreLogo.png
+
+
+ 6.2.1
+ 6.2.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/DetailPage.xaml b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/DetailPage.xaml
new file mode 100644
index 0000000..4d7ca1f
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/DetailPage.xaml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+ *
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/DetailPage.xaml.cs b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/DetailPage.xaml.cs
new file mode 100644
index 0000000..8075d1e
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/DetailPage.xaml.cs
@@ -0,0 +1,37 @@
+using Windows.UI.ViewManagement;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Navigation;
+
+namespace GrocerApp.Pages {
+ public sealed partial class DetailPage : Page {
+
+ public DetailPage() {
+ this.InitializeComponent();
+
+ SizeChanged += DetailPage_SizeChanged;
+ }
+
+ void DetailPage_SizeChanged(object sender, SizeChangedEventArgs e) {
+ //if (ApplicationView.Value == ApplicationViewState.Snapped) {
+ // GridLayout.ColumnDefinitions[0].Width
+ // = new GridLength(0);
+ //} else {
+ // GridLayout.ColumnDefinitions[0].Width
+ // = new GridLength(1, GridUnitType.Star);
+ //}
+
+ string stateName = ApplicationView.Value ==
+ ApplicationViewState.Snapped ? "Snapped" : "Others";
+ VisualStateManager.GoToState(this, stateName, false);
+
+ }
+
+ private void HandleButtonClick(object sender, RoutedEventArgs e) {
+ Windows.UI.ViewManagement.ApplicationView.TryUnsnap();
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+ }
+ }
+}
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/ItemDetail.xaml b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/ItemDetail.xaml
new file mode 100644
index 0000000..d5be62b
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/ItemDetail.xaml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/ItemDetail.xaml.cs b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/ItemDetail.xaml.cs
new file mode 100644
index 0000000..00b0b90
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/ItemDetail.xaml.cs
@@ -0,0 +1,73 @@
+using GrocerApp.Data;
+using System;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Navigation;
+
+namespace GrocerApp.Pages {
+
+ public sealed partial class ItemDetail : Page {
+ private ViewModel viewModel;
+
+ public ItemDetail() {
+ this.InitializeComponent();
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+
+ viewModel = e.Parameter as ViewModel;
+ this.DataContext = viewModel;
+
+ viewModel.PropertyChanged += (sender, eventArgs) => {
+ if (eventArgs.PropertyName == "SelectedItemIndex") {
+ if (viewModel.SelectedItemIndex == -1) {
+ SetItemDetail(null);
+ } else {
+ SetItemDetail(viewModel.GroceryList
+ [viewModel.SelectedItemIndex]);
+ }
+ }
+ };
+ SetItemDetail(viewModel.GroceryList[viewModel.SelectedItemIndex]);
+ }
+
+ private void SetItemDetail(GroceryItem item) {
+ ItemDetailName.Text = (item == null) ? "" : item.Name;
+ ItemDetailQuantity.Text = (item == null) ? ""
+ : item.Quantity.ToString();
+
+ if (item != null) {
+ ItemDetailStore.SelectedItem = item.Store;
+ } else {
+ ItemDetailStore.SelectedIndex = -1;
+ }
+ }
+
+ private void HandleItemChange(object sender, RoutedEventArgs e) {
+ if (viewModel.SelectedItemIndex > -1) {
+
+ GroceryItem selectedItem = viewModel.GroceryList
+ [viewModel.SelectedItemIndex];
+
+ if (sender == ItemDetailName) {
+ selectedItem.Name = ItemDetailName.Text;
+
+ } else if (sender == ItemDetailQuantity) {
+ int intVal;
+ bool parsed = Int32.TryParse(ItemDetailQuantity.Text,
+ out intVal);
+ if (parsed) {
+ selectedItem.Quantity = intVal;
+ }
+ } else if (sender == ItemDetailStore) {
+ string store = (String)((ComboBox)sender).SelectedItem;
+
+ if (store != null) {
+ viewModel.GroceryList
+ [viewModel.SelectedItemIndex].Store = store;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/ListPage.xaml b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/ListPage.xaml
new file mode 100644
index 0000000..b40d7c1
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/ListPage.xaml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/ListPage.xaml.cs b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/ListPage.xaml.cs
new file mode 100644
index 0000000..2ed1af8
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/ListPage.xaml.cs
@@ -0,0 +1,51 @@
+using GrocerApp.Data;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Navigation;
+
+namespace GrocerApp.Pages {
+
+ public sealed partial class ListPage : Page {
+ ViewModel viewModel;
+
+ public ListPage() {
+ this.InitializeComponent();
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+ viewModel = (ViewModel)e.Parameter;
+
+ ItemDetailFrame.Navigate(typeof(NoItemSelected));
+ viewModel.PropertyChanged += (sender, args) => {
+ if (args.PropertyName == "SelectedItemIndex") {
+ if (viewModel.SelectedItemIndex == -1) {
+ ItemDetailFrame.Navigate(typeof(NoItemSelected));
+ AppBarDoneButton.IsEnabled = false;
+ } else {
+ ItemDetailFrame.Navigate(typeof(ItemDetail), viewModel);
+ AppBarDoneButton.IsEnabled = true;
+ }
+ }
+ };
+ }
+
+ private void ListSelectionChanged(object sender, SelectionChangedEventArgs e) {
+ viewModel.SelectedItemIndex = groceryList.SelectedIndex;
+ }
+
+ private void AppBarButtonClick(object sender, RoutedEventArgs e) {
+ if (e.OriginalSource == AppBarDoneButton
+ && viewModel.SelectedItemIndex > -1) {
+
+ viewModel.GroceryList.RemoveAt(viewModel.SelectedItemIndex);
+ viewModel.SelectedItemIndex = -1;
+
+ } else if (e.OriginalSource == AppBarZipButton) {
+ HomeZipFlyout.Show(this, this.BottomAppBar, (Button)e.OriginalSource);
+ } else if (e.OriginalSource == AppBarAddButton) {
+ AddItemFlyout.Show(this, this.BottomAppBar, (Button)e.OriginalSource);
+ }
+
+ }
+ }
+}
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/MainPage.xaml b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/MainPage.xaml
new file mode 100644
index 0000000..9d3d3ef
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/MainPage.xaml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/MainPage.xaml.cs b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/MainPage.xaml.cs
new file mode 100644
index 0000000..880c881
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/MainPage.xaml.cs
@@ -0,0 +1,125 @@
+using GrocerApp.Data;
+using System;
+using Windows.Data.Xml.Dom;
+using Windows.UI.Notifications;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Navigation;
+using System.Collections.Generic;
+
+namespace GrocerApp.Pages {
+
+ public sealed partial class MainPage : Page {
+ private ViewModel viewModel;
+
+ public MainPage() {
+ this.InitializeComponent();
+
+ viewModel = new ViewModel();
+
+ viewModel.StoreList.Add("Whole Foods");
+ viewModel.StoreList.Add("Kroger");
+ viewModel.StoreList.Add("Costco");
+ viewModel.StoreList.Add("Walmart");
+
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Apples",
+ Quantity = 4, Store = "Whole Foods"
+ });
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Hotdogs",
+ Quantity = 12, Store = "Costco"
+ });
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Soda",
+ Quantity = 2, Store = "Costco"
+ });
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Eggs",
+ Quantity = 12, Store = "Kroger"
+ });
+
+ this.DataContext = viewModel;
+
+ MainFrame.Navigate(typeof(ListPage), viewModel);
+
+ viewModel.GroceryList.CollectionChanged += (sender, args) => {
+ UpdateTile();
+ UpdateBadge();
+ };
+
+ UpdateTile();
+ UpdateBadge();
+ }
+
+ private void UpdateBadge() {
+
+ int itemCount = viewModel.GroceryList.Count;
+
+ BadgeTemplateType templateType = itemCount > 3
+ ? BadgeTemplateType.BadgeGlyph : BadgeTemplateType.BadgeNumber;
+
+ XmlDocument badgeXml = BadgeUpdateManager.GetTemplateContent(templateType);
+ ((XmlElement)badgeXml.GetElementsByTagName("badge")[0]).SetAttribute("value",
+ (itemCount > 3) ? "alert" : itemCount.ToString());
+
+ for (int i = 0; i < 5; i++) {
+ BadgeUpdateManager.CreateBadgeUpdaterForApplication()
+ .Update(new BadgeNotification(badgeXml));
+ }
+
+ }
+
+ private void UpdateTile() {
+
+ int storeCount = 0;
+ System.Collections.Generic.List storeNames
+ = new System.Collections.Generic.List();
+
+ for (int i = 0; i < viewModel.GroceryList.Count; i++) {
+ if (!storeNames.Contains(viewModel.GroceryList[i].Store)) {
+ storeCount++;
+ storeNames.Add(viewModel.GroceryList[i].Store);
+ }
+ }
+
+ XmlDocument narrowTileXml = TileUpdateManager
+ .GetTemplateContent(TileTemplateType.TileSquareText03);
+ XmlDocument wideTileXml = TileUpdateManager
+ .GetTemplateContent(TileTemplateType.TileWideBlockAndText01);
+
+ XmlNodeList narrowTextNodes = narrowTileXml.GetElementsByTagName("text");
+ XmlNodeList wideTextNodes = wideTileXml.GetElementsByTagName("text");
+
+ for (int i = 0; i < narrowTextNodes.Length
+ && i < viewModel.GroceryList.Count; i++) {
+
+ GroceryItem item = viewModel.GroceryList[i];
+ narrowTextNodes[i].InnerText = item.Name;
+ wideTextNodes[i].InnerText = String.Format("{0} ({1})", item.Name, item.Store);
+ }
+
+ wideTextNodes[4].InnerText = storeCount.ToString();
+ wideTextNodes[5].InnerText = "Stores";
+
+ var wideBindingElement = wideTileXml.GetElementsByTagName("binding")[0];
+ var importedNode = narrowTileXml.ImportNode(wideBindingElement, true);
+ narrowTileXml.GetElementsByTagName("visual")[0].AppendChild(importedNode);
+
+ for (int i = 0; i < 5; i++) {
+ TileUpdateManager.CreateTileUpdaterForApplication()
+ .Update(new TileNotification(narrowTileXml));
+ }
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+ }
+
+ private void NavBarButtonPress(object sender, RoutedEventArgs e) {
+ Boolean isListView = (Button)sender == ListViewButton;
+ MainFrame.Navigate(isListView ? typeof(ListPage)
+ : typeof(DetailPage), viewModel);
+
+ }
+ }
+}
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml
new file mode 100644
index 0000000..484abad
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml.cs b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml.cs
new file mode 100644
index 0000000..65510c8
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+using Windows.UI.Xaml.Data;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Navigation;
+
+// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
+
+namespace GrocerApp.Pages {
+ ///
+ /// An empty page that can be used on its own or navigated to within a Frame.
+ ///
+ public sealed partial class NoItemSelected : Page {
+ public NoItemSelected() {
+ this.InitializeComponent();
+ }
+
+ ///
+ /// Invoked when this page is about to be displayed in a Frame.
+ ///
+ /// Event data that describes how this page was reached. The Parameter
+ /// property is typically used to configure the page.
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+ }
+ }
+}
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Properties/AssemblyInfo.cs b/Source Code/Chapter 4/GrocerApp/GrocerApp/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..f2e348e
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Properties/AssemblyInfo.cs
@@ -0,0 +1,29 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GrocerApp")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("GrocerApp")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/Source Code/Chapter 4/GrocerApp/GrocerApp/Resources/GrocerResourceDictionary.xaml b/Source Code/Chapter 4/GrocerApp/GrocerApp/Resources/GrocerResourceDictionary.xaml
new file mode 100644
index 0000000..40867bb
--- /dev/null
+++ b/Source Code/Chapter 4/GrocerApp/GrocerApp/Resources/GrocerResourceDictionary.xaml
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder.sln b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder.sln
new file mode 100644
index 0000000..077c887
--- /dev/null
+++ b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder.sln
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 2012 for Windows 8
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LayoutPlaceHolder", "LayoutPlaceHolder\LayoutPlaceHolder.csproj", "{B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|ARM = Debug|ARM
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|ARM = Release|ARM
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Debug|ARM.ActiveCfg = Debug|ARM
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Debug|ARM.Build.0 = Debug|ARM
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Debug|ARM.Deploy.0 = Debug|ARM
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Debug|x64.ActiveCfg = Debug|x64
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Debug|x64.Build.0 = Debug|x64
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Debug|x64.Deploy.0 = Debug|x64
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Debug|x86.ActiveCfg = Debug|x86
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Debug|x86.Build.0 = Debug|x86
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Debug|x86.Deploy.0 = Debug|x86
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Release|ARM.ActiveCfg = Release|ARM
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Release|ARM.Build.0 = Release|ARM
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Release|ARM.Deploy.0 = Release|ARM
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Release|x64.ActiveCfg = Release|x64
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Release|x64.Build.0 = Release|x64
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Release|x64.Deploy.0 = Release|x64
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Release|x86.ActiveCfg = Release|x86
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Release|x86.Build.0 = Release|x86
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}.Release|x86.Deploy.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder.v11.suo b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder.v11.suo
new file mode 100644
index 0000000..d7d289f
Binary files /dev/null and b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder.v11.suo differ
diff --git a/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/App.xaml b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/App.xaml
new file mode 100644
index 0000000..e24c404
--- /dev/null
+++ b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/App.xaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/App.xaml.cs b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/App.xaml.cs
new file mode 100644
index 0000000..44e0eaf
--- /dev/null
+++ b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/App.xaml.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Windows.ApplicationModel;
+using Windows.ApplicationModel.Activation;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+using Windows.UI.Xaml.Data;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Navigation;
+
+namespace LayoutPlaceHolder {
+ sealed partial class App : Application {
+ public App() {
+ this.InitializeComponent();
+ this.Suspending += OnSuspending;
+ }
+
+ protected override void OnLaunched(LaunchActivatedEventArgs args) {
+ Frame rootFrame = Window.Current.Content as Frame;
+
+ // Do not repeat app initialization when the Window already has content,
+ // just ensure that the window is active
+ if (rootFrame == null) {
+ // Create a Frame to act as the navigation context and navigate to the first page
+ rootFrame = new Frame();
+
+ if (args.PreviousExecutionState == ApplicationExecutionState.Terminated) {
+ //TODO: Load state from previously suspended application
+ }
+
+ // Place the frame in the current Window
+ Window.Current.Content = rootFrame;
+ }
+
+ if (rootFrame.Content == null) {
+ // When the navigation stack isn't restored navigate to the first page,
+ // configuring the new page by passing required information as a navigation
+ // parameter
+ if (!rootFrame.Navigate(typeof(MainPage), args.Arguments)) {
+ throw new Exception("Failed to create initial page");
+ }
+ }
+ // Ensure the current window is active
+ Window.Current.Activate();
+ }
+
+ private void OnSuspending(object sender, SuspendingEventArgs e) {
+ var deferral = e.SuspendingOperation.GetDeferral();
+ //TODO: Save application state and stop any background activity
+ deferral.Complete();
+ }
+ }
+}
diff --git a/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Assets/Logo.png b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Assets/Logo.png
new file mode 100644
index 0000000..e26771c
Binary files /dev/null and b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Assets/Logo.png differ
diff --git a/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Assets/SmallLogo.png b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Assets/SmallLogo.png
new file mode 100644
index 0000000..1eb0d9d
Binary files /dev/null and b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Assets/SmallLogo.png differ
diff --git a/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Assets/SplashScreen.png b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Assets/SplashScreen.png
new file mode 100644
index 0000000..c951e03
Binary files /dev/null and b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Assets/SplashScreen.png differ
diff --git a/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Assets/StoreLogo.png b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Assets/StoreLogo.png
new file mode 100644
index 0000000..dcb6727
Binary files /dev/null and b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Assets/StoreLogo.png differ
diff --git a/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Common/StandardStyles.xaml b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Common/StandardStyles.xaml
new file mode 100644
index 0000000..85f4ed6
--- /dev/null
+++ b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Common/StandardStyles.xaml
@@ -0,0 +1,1829 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mouse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/LayoutPlaceHolder.csproj b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/LayoutPlaceHolder.csproj
new file mode 100644
index 0000000..b644c87
--- /dev/null
+++ b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/LayoutPlaceHolder.csproj
@@ -0,0 +1,151 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {B4EEF9AB-D9DB-49C0-9EE1-CAB95E3187EC}
+ AppContainerExe
+ Properties
+ LayoutPlaceHolder
+ LayoutPlaceHolder
+ en-US
+ 512
+ {BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ LayoutPlaceHolder_TemporaryKey.pfx
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE;NETFX_CORE
+ prompt
+ 4
+
+
+ true
+ bin\ARM\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ ARM
+ false
+ prompt
+ true
+
+
+ bin\ARM\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ ARM
+ false
+ prompt
+ true
+
+
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ x64
+ false
+ prompt
+ true
+
+
+ bin\x64\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ x64
+ false
+ prompt
+ true
+
+
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ x86
+ false
+ prompt
+ true
+
+
+ bin\x86\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ x86
+ false
+ prompt
+ true
+
+
+
+
+
+
+ App.xaml
+
+
+ MainPage.xaml
+
+
+
+
+
+ Designer
+
+
+
+
+
+
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+ 11.0
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/LayoutPlaceHolder.csproj.user b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/LayoutPlaceHolder.csproj.user
new file mode 100644
index 0000000..b29230c
--- /dev/null
+++ b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/LayoutPlaceHolder.csproj.user
@@ -0,0 +1,6 @@
+
+
+
+ True
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/LayoutPlaceHolder_TemporaryKey.pfx b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/LayoutPlaceHolder_TemporaryKey.pfx
new file mode 100644
index 0000000..190d788
Binary files /dev/null and b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/LayoutPlaceHolder_TemporaryKey.pfx differ
diff --git a/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/MainPage.xaml b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/MainPage.xaml
new file mode 100644
index 0000000..a54fd9d
--- /dev/null
+++ b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/MainPage.xaml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/MainPage.xaml.cs b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/MainPage.xaml.cs
new file mode 100644
index 0000000..d529c14
--- /dev/null
+++ b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/MainPage.xaml.cs
@@ -0,0 +1,37 @@
+using System;
+using Windows.UI.ViewManagement;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Navigation;
+
+// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
+
+namespace LayoutPlaceHolder
+{
+ ///
+ /// An empty page that can be used on its own or navigated to within a Frame.
+ ///
+ public sealed partial class MainPage : Page
+ {
+ public MainPage()
+ {
+ this.InitializeComponent();
+
+ SizeChanged += MainPage_SizeChanged;
+ }
+
+ void MainPage_SizeChanged(object sender, SizeChangedEventArgs e) {
+ TB.Text = String.Format("({0})", Enum.GetName(typeof(ApplicationViewState), ApplicationView.Value));
+
+ }
+
+ ///
+ /// Invoked when this page is about to be displayed in a Frame.
+ ///
+ /// Event data that describes how this page was reached. The Parameter
+ /// property is typically used to configure the page.
+ protected override void OnNavigatedTo(NavigationEventArgs e)
+ {
+ }
+ }
+}
diff --git a/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Package.appxmanifest b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Package.appxmanifest
new file mode 100644
index 0000000..348bc81
--- /dev/null
+++ b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Package.appxmanifest
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+ LayoutPlaceHolder
+ adam
+ Assets\StoreLogo.png
+
+
+
+ 6.2.1
+ 6.2.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Properties/AssemblyInfo.cs b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..d1b6003
--- /dev/null
+++ b/Source Code/Chapter 4/LayoutPlaceHolder/LayoutPlaceHolder/Properties/AssemblyInfo.cs
@@ -0,0 +1,29 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("LayoutPlaceHolder")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("LayoutPlaceHolder")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp.sln b/Source Code/Chapter 5/GrocerApp/GrocerApp.sln
new file mode 100644
index 0000000..9185511
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp.sln
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Express 2012 for Windows 8
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrocerApp", "GrocerApp\GrocerApp.csproj", "{2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|ARM = Debug|ARM
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|ARM = Release|ARM
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|ARM.ActiveCfg = Debug|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|ARM.Build.0 = Debug|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|ARM.Deploy.0 = Debug|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x64.ActiveCfg = Debug|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x64.Build.0 = Debug|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x64.Deploy.0 = Debug|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x86.ActiveCfg = Debug|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x86.Build.0 = Debug|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Debug|x86.Deploy.0 = Debug|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|ARM.ActiveCfg = Release|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|ARM.Build.0 = Release|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|ARM.Deploy.0 = Release|ARM
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x64.ActiveCfg = Release|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x64.Build.0 = Release|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x64.Deploy.0 = Release|x64
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x86.ActiveCfg = Release|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x86.Build.0 = Release|x86
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}.Release|x86.Deploy.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp.v11.suo b/Source Code/Chapter 5/GrocerApp/GrocerApp.v11.suo
new file mode 100644
index 0000000..0f86fef
Binary files /dev/null and b/Source Code/Chapter 5/GrocerApp/GrocerApp.v11.suo differ
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/App.xaml b/Source Code/Chapter 5/GrocerApp/GrocerApp/App.xaml
new file mode 100644
index 0000000..fc45fa5
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/App.xaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/App.xaml.cs b/Source Code/Chapter 5/GrocerApp/GrocerApp/App.xaml.cs
new file mode 100644
index 0000000..acb1a72
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/App.xaml.cs
@@ -0,0 +1,106 @@
+using GrocerApp.Data;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Windows.ApplicationModel;
+using Windows.ApplicationModel.Activation;
+using Windows.UI.Core;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace GrocerApp {
+
+ sealed partial class App : Application {
+ private ViewModel viewModel;
+ private Task locationTask;
+ private CancellationTokenSource locationTokenSource;
+
+ public App() {
+ this.InitializeComponent();
+
+ viewModel = new ViewModel();
+
+ viewModel.StoreList.Add("Whole Foods");
+ viewModel.StoreList.Add("Kroger");
+ viewModel.StoreList.Add("Costco");
+ viewModel.StoreList.Add("Walmart");
+
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Apples",
+ Quantity = 4, Store = "Whole Foods"
+ });
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Hotdogs",
+ Quantity = 12, Store = "Costco"
+ });
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Soda",
+ Quantity = 2, Store = "Costco"
+ });
+ viewModel.GroceryList.Add(new GroceryItem {
+ Name = "Eggs",
+ Quantity = 12, Store = "Kroger"
+ });
+
+ this.Suspending += OnSuspending;
+ this.Resuming += OnResuming;
+ }
+
+ protected override void OnLaunched(LaunchActivatedEventArgs args) {
+ Frame rootFrame = Window.Current.Content as Frame;
+
+ if (rootFrame == null) {
+ rootFrame = new Frame();
+ if (args.PreviousExecutionState == ApplicationExecutionState.Terminated) {
+ //TODO: Load state from previously suspended application
+ }
+ Window.Current.Content = rootFrame;
+ }
+
+ if (rootFrame.Content == null) {
+
+ if (!rootFrame.Navigate(typeof(Pages.MainPage), viewModel)) {
+ throw new Exception("Failed to create initial page");
+ }
+ }
+ Window.Current.Activate();
+ StartLocationTracking(rootFrame);
+ }
+
+ protected override void OnSearchActivated(SearchActivatedEventArgs args) {
+ viewModel.SearchAndSelect(args.QueryText);
+ }
+
+ private void OnResuming(object sender, object e) {
+ viewModel.Location = "Unknown";
+ StartLocationTracking(Window.Current.Content as Frame);
+ }
+
+ private void OnSuspending(object sender, SuspendingEventArgs e) {
+ StopLocationTracking();
+ SuspendingDeferral deferral = e.SuspendingOperation.GetDeferral();
+ locationTask.Wait();
+ deferral.Complete();
+ }
+
+ private void StartLocationTracking(Frame frame) {
+ locationTokenSource = new CancellationTokenSource();
+ CancellationToken token = locationTokenSource.Token;
+
+ locationTask = new Task(async () => {
+ while (!token.IsCancellationRequested) {
+ await frame.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
+ async () => {
+ viewModel.Location = await Location.TrackLocation();
+ });
+ token.WaitHandle.WaitOne(5000);
+ }
+ });
+ locationTask.Start();
+ }
+
+ private void StopLocationTracking() {
+ locationTokenSource.Cancel();
+ }
+ }
+}
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/Logo.png b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/Logo.png
new file mode 100644
index 0000000..e26771c
Binary files /dev/null and b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/Logo.png differ
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/SmallLogo.png b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/SmallLogo.png
new file mode 100644
index 0000000..1eb0d9d
Binary files /dev/null and b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/SmallLogo.png differ
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/SplashScreen.png b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/SplashScreen.png
new file mode 100644
index 0000000..c951e03
Binary files /dev/null and b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/SplashScreen.png differ
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/StoreLogo.png b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/StoreLogo.png
new file mode 100644
index 0000000..dcb6727
Binary files /dev/null and b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/StoreLogo.png differ
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/Thumbs.db b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/Thumbs.db
new file mode 100644
index 0000000..46d617a
Binary files /dev/null and b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/Thumbs.db differ
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/tile150.png b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/tile150.png
new file mode 100644
index 0000000..bcc4f79
Binary files /dev/null and b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/tile150.png differ
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/tile30.png b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/tile30.png
new file mode 100644
index 0000000..bcc4e65
Binary files /dev/null and b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/tile30.png differ
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/tile310.png b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/tile310.png
new file mode 100644
index 0000000..e5f26ad
Binary files /dev/null and b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/tile310.png differ
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/tile620.png b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/tile620.png
new file mode 100644
index 0000000..c8e2fb9
Binary files /dev/null and b/Source Code/Chapter 5/GrocerApp/GrocerApp/Assets/tile620.png differ
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Common/StandardStyles.xaml b/Source Code/Chapter 5/GrocerApp/GrocerApp/Common/StandardStyles.xaml
new file mode 100644
index 0000000..1afaf54
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Common/StandardStyles.xaml
@@ -0,0 +1,1837 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Mouse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Data/GroceryItem.cs b/Source Code/Chapter 5/GrocerApp/GrocerApp/Data/GroceryItem.cs
new file mode 100644
index 0000000..092be51
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Data/GroceryItem.cs
@@ -0,0 +1,31 @@
+using System.ComponentModel;
+
+namespace GrocerApp.Data {
+
+ public class GroceryItem : INotifyPropertyChanged {
+ private string name, store;
+ private int quantity;
+
+ public string Name {
+ get { return name; }
+ set { name = value; NotifyPropertyChanged("Name"); }
+ }
+
+ public int Quantity {
+ get { return quantity; }
+ set { quantity = value; NotifyPropertyChanged("Quantity"); }
+ }
+
+ public string Store {
+ get { return store; }
+ set { store = value; NotifyPropertyChanged("Store"); }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ private void NotifyPropertyChanged(string propName) {
+ if (PropertyChanged != null) {
+ PropertyChanged(this, new PropertyChangedEventArgs(propName));
+ }
+ }
+ }
+}
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Data/Location.cs b/Source Code/Chapter 5/GrocerApp/GrocerApp/Data/Location.cs
new file mode 100644
index 0000000..efe7f6b
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Data/Location.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Windows.Data.Json;
+using Windows.Devices.Geolocation;
+
+namespace GrocerApp.Data {
+ class Location {
+
+ public static async Task TrackLocation() {
+ Geolocator geoloc = new Geolocator();
+ Geoposition position = await geoloc.GetGeopositionAsync();
+
+ HttpClient httpClient = new HttpClient();
+ httpClient.BaseAddress = new Uri("http://nominatim.openstreetmap.org");
+ HttpResponseMessage httpResult = await httpClient.GetAsync(
+ String.Format("reverse?format=json&lat={0}&lon={1}",
+ position.Coordinate.Latitude, position.Coordinate.Longitude));
+
+ JsonObject jsonObject = JsonObject
+ .Parse(await httpResult.Content.ReadAsStringAsync());
+
+ return jsonObject.GetNamedObject("address")
+ .GetNamedString("road") + DateTime.Now.ToString("' ('HH:mm:ss')'");
+ }
+ }
+}
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Data/ViewModel.cs b/Source Code/Chapter 5/GrocerApp/GrocerApp/Data/ViewModel.cs
new file mode 100644
index 0000000..dbe0eff
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Data/ViewModel.cs
@@ -0,0 +1,70 @@
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+
+namespace GrocerApp.Data {
+
+ public class ViewModel : INotifyPropertyChanged {
+ private ObservableCollection groceryList;
+ private List storeList;
+ private int selectedItemIndex;
+ private string homeZipCode;
+ private string location;
+
+ public ViewModel() {
+ groceryList = new ObservableCollection();
+ storeList = new List();
+ selectedItemIndex = -1;
+ homeZipCode = "NY 10118";
+ location = "Unknown";
+ }
+
+ public void SearchAndSelect(string searchTerm) {
+ int selIndex = -1;
+ for (int i = 0; i < GroceryList.Count; i++) {
+ if (GroceryList[i].Name.ToLower().Contains(searchTerm.ToLower())) {
+ selIndex = i;
+ break;
+ }
+ }
+ SelectedItemIndex = selIndex;
+ }
+
+ public string Location {
+ get { return location; }
+ set { location = value; NotifyPropertyChanged("Location"); }
+ }
+
+ public string HomeZipCode {
+ get { return homeZipCode; }
+ set { homeZipCode = value; NotifyPropertyChanged("HomeZipCode"); }
+ }
+
+ public int SelectedItemIndex {
+ get { return selectedItemIndex; }
+ set {
+ selectedItemIndex = value; NotifyPropertyChanged("SelectedItemIndex");
+ }
+ }
+
+ public ObservableCollection GroceryList {
+ get {
+ return groceryList;
+ }
+ }
+
+ public List StoreList {
+ get {
+ return storeList;
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+ private void NotifyPropertyChanged(string propName) {
+ if (PropertyChanged != null) {
+ PropertyChanged(this, new PropertyChangedEventArgs(propName));
+ }
+ }
+ }
+
+}
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml b/Source Code/Chapter 5/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml
new file mode 100644
index 0000000..b4d917e
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml.cs b/Source Code/Chapter 5/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml.cs
new file mode 100644
index 0000000..ed84b26
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Flyouts/AddItemFlyout.xaml.cs
@@ -0,0 +1,29 @@
+using System;
+using GrocerApp.Data;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace GrocerApp.Flyouts {
+ public sealed partial class AddItemFlyout : UserControl {
+
+ public AddItemFlyout() {
+ this.InitializeComponent();
+ }
+
+ public void Show(Page page, AppBar appbar, Button button) {
+ AddItemPopup.IsOpen = true;
+ FlyoutHelper.ShowRelativeToAppBar(AddItemPopup, page, appbar, button);
+ }
+
+ private void AddButtonClick(object sender, RoutedEventArgs e) {
+
+ ((ViewModel)DataContext).GroceryList.Add(new GroceryItem {
+ Name = ItemName.Text,
+ Quantity = Int32.Parse(ItemQuantity.Text),
+ Store = ItemStore.SelectedItem.ToString()
+ });
+
+ AddItemPopup.IsOpen = false;
+ }
+ }
+}
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Flyouts/FlyoutHelper.cs b/Source Code/Chapter 5/GrocerApp/GrocerApp/Flyouts/FlyoutHelper.cs
new file mode 100644
index 0000000..23de22a
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Flyouts/FlyoutHelper.cs
@@ -0,0 +1,38 @@
+using System;
+using Windows.Foundation;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+
+namespace GrocerApp.Flyouts {
+ class FlyoutHelper {
+
+ public static void ShowRelativeToAppBar(Popup popup, Page page,
+ AppBar appbar, Button button) {
+
+ Func getOffset =
+ delegate(UIElement control1, UIElement control2) {
+ return control1.TransformToVisual(control2)
+ .TransformPoint(new Point(0, 0));
+ };
+
+ Point popupOffset = getOffset(popup, page);
+
+ Point buttonOffset = getOffset(button, page);
+ popup.HorizontalOffset = buttonOffset.X - popupOffset.X
+ - (popup.ActualWidth / 2) + (button.ActualWidth / 2);
+ popup.VerticalOffset = getOffset(appbar, page).Y
+ - popupOffset.Y - popup.ActualHeight;
+
+ if (popupOffset.X + popup.HorizontalOffset
+ + popup.ActualWidth > page.ActualWidth) {
+
+ popup.HorizontalOffset = page.ActualWidth
+ - popupOffset.X - popup.ActualWidth;
+ } else if (popup.HorizontalOffset + popupOffset.X < 0) {
+ popup.HorizontalOffset = -popupOffset.X;
+ }
+ }
+
+ }
+}
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml b/Source Code/Chapter 5/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml
new file mode 100644
index 0000000..7edbf11
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml.cs b/Source Code/Chapter 5/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml.cs
new file mode 100644
index 0000000..081555e
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Flyouts/HomeZipCodeFlyout.xaml.cs
@@ -0,0 +1,20 @@
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace GrocerApp.Flyouts {
+ public sealed partial class HomeZipCodeFlyout : UserControl {
+
+ public HomeZipCodeFlyout() {
+ this.InitializeComponent();
+ }
+
+ public void Show(Page page, AppBar appbar, Button button) {
+ HomeZipCodePopup.IsOpen = true;
+ FlyoutHelper.ShowRelativeToAppBar(HomeZipCodePopup, page, appbar, button);
+ }
+
+ private void OKButtonClick(object sender, RoutedEventArgs e) {
+ HomeZipCodePopup.IsOpen = false;
+ }
+ }
+}
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/GrocerApp.csproj b/Source Code/Chapter 5/GrocerApp/GrocerApp/GrocerApp.csproj
new file mode 100644
index 0000000..96e2d20
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/GrocerApp.csproj
@@ -0,0 +1,206 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {2EB6BE9C-103F-4FEE-B353-B58F06CABCF2}
+ AppContainerExe
+ Properties
+ GrocerApp
+ GrocerApp
+ en-US
+ 512
+ {BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ GrocerApp_TemporaryKey.pfx
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE;NETFX_CORE
+ prompt
+ 4
+
+
+ true
+ bin\ARM\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ ARM
+ false
+ prompt
+ true
+
+
+ bin\ARM\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ ARM
+ false
+ prompt
+ true
+
+
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ x64
+ false
+ prompt
+ true
+
+
+ bin\x64\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ x64
+ false
+ prompt
+ true
+
+
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE;NETFX_CORE
+ ;2008
+ full
+ x86
+ false
+ prompt
+ true
+
+
+ bin\x86\Release\
+ TRACE;NETFX_CORE
+ true
+ ;2008
+ pdbonly
+ x86
+ false
+ prompt
+ true
+
+
+
+
+
+
+ App.xaml
+
+
+
+
+
+ AddItemFlyout.xaml
+
+
+
+ HomeZipCodeFlyout.xaml
+
+
+ DetailPage.xaml
+
+
+ ItemDetail.xaml
+
+
+ ListPage.xaml
+
+
+ MainPage.xaml
+
+
+ NoItemSelected.xaml
+
+
+
+
+
+ Designer
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+ Designer
+ PreserveNewest
+ MSBuild:Compile
+
+
+ Designer
+ MSBuild:Compile
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+ 11.0
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/GrocerApp.csproj.user b/Source Code/Chapter 5/GrocerApp/GrocerApp/GrocerApp.csproj.user
new file mode 100644
index 0000000..b29230c
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/GrocerApp.csproj.user
@@ -0,0 +1,6 @@
+
+
+
+ True
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/GrocerApp_TemporaryKey.pfx b/Source Code/Chapter 5/GrocerApp/GrocerApp/GrocerApp_TemporaryKey.pfx
new file mode 100644
index 0000000..27d6028
Binary files /dev/null and b/Source Code/Chapter 5/GrocerApp/GrocerApp/GrocerApp_TemporaryKey.pfx differ
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Package.appxmanifest b/Source Code/Chapter 5/GrocerApp/GrocerApp/Package.appxmanifest
new file mode 100644
index 0000000..b24cbfe
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Package.appxmanifest
@@ -0,0 +1,31 @@
+
+
+
+
+ GrocerApp
+ adam
+ Assets\StoreLogo.png
+
+
+ 6.2.1
+ 6.2.1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/DetailPage.xaml b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/DetailPage.xaml
new file mode 100644
index 0000000..4d7ca1f
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/DetailPage.xaml
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+ *
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/DetailPage.xaml.cs b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/DetailPage.xaml.cs
new file mode 100644
index 0000000..8075d1e
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/DetailPage.xaml.cs
@@ -0,0 +1,37 @@
+using Windows.UI.ViewManagement;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Navigation;
+
+namespace GrocerApp.Pages {
+ public sealed partial class DetailPage : Page {
+
+ public DetailPage() {
+ this.InitializeComponent();
+
+ SizeChanged += DetailPage_SizeChanged;
+ }
+
+ void DetailPage_SizeChanged(object sender, SizeChangedEventArgs e) {
+ //if (ApplicationView.Value == ApplicationViewState.Snapped) {
+ // GridLayout.ColumnDefinitions[0].Width
+ // = new GridLength(0);
+ //} else {
+ // GridLayout.ColumnDefinitions[0].Width
+ // = new GridLength(1, GridUnitType.Star);
+ //}
+
+ string stateName = ApplicationView.Value ==
+ ApplicationViewState.Snapped ? "Snapped" : "Others";
+ VisualStateManager.GoToState(this, stateName, false);
+
+ }
+
+ private void HandleButtonClick(object sender, RoutedEventArgs e) {
+ Windows.UI.ViewManagement.ApplicationView.TryUnsnap();
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+ }
+ }
+}
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/ItemDetail.xaml b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/ItemDetail.xaml
new file mode 100644
index 0000000..d5be62b
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/ItemDetail.xaml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/ItemDetail.xaml.cs b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/ItemDetail.xaml.cs
new file mode 100644
index 0000000..00b0b90
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/ItemDetail.xaml.cs
@@ -0,0 +1,73 @@
+using GrocerApp.Data;
+using System;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Navigation;
+
+namespace GrocerApp.Pages {
+
+ public sealed partial class ItemDetail : Page {
+ private ViewModel viewModel;
+
+ public ItemDetail() {
+ this.InitializeComponent();
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+
+ viewModel = e.Parameter as ViewModel;
+ this.DataContext = viewModel;
+
+ viewModel.PropertyChanged += (sender, eventArgs) => {
+ if (eventArgs.PropertyName == "SelectedItemIndex") {
+ if (viewModel.SelectedItemIndex == -1) {
+ SetItemDetail(null);
+ } else {
+ SetItemDetail(viewModel.GroceryList
+ [viewModel.SelectedItemIndex]);
+ }
+ }
+ };
+ SetItemDetail(viewModel.GroceryList[viewModel.SelectedItemIndex]);
+ }
+
+ private void SetItemDetail(GroceryItem item) {
+ ItemDetailName.Text = (item == null) ? "" : item.Name;
+ ItemDetailQuantity.Text = (item == null) ? ""
+ : item.Quantity.ToString();
+
+ if (item != null) {
+ ItemDetailStore.SelectedItem = item.Store;
+ } else {
+ ItemDetailStore.SelectedIndex = -1;
+ }
+ }
+
+ private void HandleItemChange(object sender, RoutedEventArgs e) {
+ if (viewModel.SelectedItemIndex > -1) {
+
+ GroceryItem selectedItem = viewModel.GroceryList
+ [viewModel.SelectedItemIndex];
+
+ if (sender == ItemDetailName) {
+ selectedItem.Name = ItemDetailName.Text;
+
+ } else if (sender == ItemDetailQuantity) {
+ int intVal;
+ bool parsed = Int32.TryParse(ItemDetailQuantity.Text,
+ out intVal);
+ if (parsed) {
+ selectedItem.Quantity = intVal;
+ }
+ } else if (sender == ItemDetailStore) {
+ string store = (String)((ComboBox)sender).SelectedItem;
+
+ if (store != null) {
+ viewModel.GroceryList
+ [viewModel.SelectedItemIndex].Store = store;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/ListPage.xaml b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/ListPage.xaml
new file mode 100644
index 0000000..b40d7c1
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/ListPage.xaml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/ListPage.xaml.cs b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/ListPage.xaml.cs
new file mode 100644
index 0000000..7391c25
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/ListPage.xaml.cs
@@ -0,0 +1,52 @@
+using GrocerApp.Data;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Navigation;
+
+namespace GrocerApp.Pages {
+
+ public sealed partial class ListPage : Page {
+ ViewModel viewModel;
+
+ public ListPage() {
+ this.InitializeComponent();
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+ viewModel = (ViewModel)e.Parameter;
+
+ ItemDetailFrame.Navigate(typeof(NoItemSelected));
+ viewModel.PropertyChanged += (sender, args) => {
+ if (args.PropertyName == "SelectedItemIndex") {
+ groceryList.SelectedIndex = viewModel.SelectedItemIndex;
+ if (viewModel.SelectedItemIndex == -1) {
+ ItemDetailFrame.Navigate(typeof(NoItemSelected));
+ AppBarDoneButton.IsEnabled = false;
+ } else {
+ ItemDetailFrame.Navigate(typeof(ItemDetail), viewModel);
+ AppBarDoneButton.IsEnabled = true;
+ }
+ }
+ };
+ }
+
+ private void ListSelectionChanged(object sender, SelectionChangedEventArgs e) {
+ viewModel.SelectedItemIndex = groceryList.SelectedIndex;
+ }
+
+ private void AppBarButtonClick(object sender, RoutedEventArgs e) {
+ if (e.OriginalSource == AppBarDoneButton
+ && viewModel.SelectedItemIndex > -1) {
+
+ viewModel.GroceryList.RemoveAt(viewModel.SelectedItemIndex);
+ viewModel.SelectedItemIndex = -1;
+
+ } else if (e.OriginalSource == AppBarZipButton) {
+ HomeZipFlyout.Show(this, this.BottomAppBar, (Button)e.OriginalSource);
+ } else if (e.OriginalSource == AppBarAddButton) {
+ AddItemFlyout.Show(this, this.BottomAppBar, (Button)e.OriginalSource);
+ }
+
+ }
+ }
+}
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/MainPage.xaml b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/MainPage.xaml
new file mode 100644
index 0000000..8b58376
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/MainPage.xaml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/MainPage.xaml.cs b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/MainPage.xaml.cs
new file mode 100644
index 0000000..5ad82c9
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/MainPage.xaml.cs
@@ -0,0 +1,100 @@
+using GrocerApp.Data;
+using System;
+using Windows.Data.Xml.Dom;
+using Windows.UI.Notifications;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Navigation;
+
+namespace GrocerApp.Pages {
+
+ public sealed partial class MainPage : Page {
+ private ViewModel viewModel;
+
+ public MainPage() {
+ this.InitializeComponent();
+ }
+
+ private void UpdateBadge() {
+
+ int itemCount = viewModel.GroceryList.Count;
+
+ BadgeTemplateType templateType = itemCount > 3
+ ? BadgeTemplateType.BadgeGlyph : BadgeTemplateType.BadgeNumber;
+
+ XmlDocument badgeXml = BadgeUpdateManager.GetTemplateContent(templateType);
+ ((XmlElement)badgeXml.GetElementsByTagName("badge")[0]).SetAttribute("value",
+ (itemCount > 3) ? "alert" : itemCount.ToString());
+
+ for (int i = 0; i < 5; i++) {
+ BadgeUpdateManager.CreateBadgeUpdaterForApplication()
+ .Update(new BadgeNotification(badgeXml));
+ }
+
+ }
+
+ private void UpdateTile() {
+
+ int storeCount = 0;
+ System.Collections.Generic.List storeNames
+ = new System.Collections.Generic.List();
+
+ for (int i = 0; i < viewModel.GroceryList.Count; i++) {
+ if (!storeNames.Contains(viewModel.GroceryList[i].Store)) {
+ storeCount++;
+ storeNames.Add(viewModel.GroceryList[i].Store);
+ }
+ }
+
+ XmlDocument narrowTileXml = TileUpdateManager
+ .GetTemplateContent(TileTemplateType.TileSquareText03);
+ XmlDocument wideTileXml = TileUpdateManager
+ .GetTemplateContent(TileTemplateType.TileWideBlockAndText01);
+
+ XmlNodeList narrowTextNodes = narrowTileXml.GetElementsByTagName("text");
+ XmlNodeList wideTextNodes = wideTileXml.GetElementsByTagName("text");
+
+ for (int i = 0; i < narrowTextNodes.Length
+ && i < viewModel.GroceryList.Count; i++) {
+
+ GroceryItem item = viewModel.GroceryList[i];
+ narrowTextNodes[i].InnerText = item.Name;
+ wideTextNodes[i].InnerText = String.Format("{0} ({1})", item.Name, item.Store);
+ }
+
+ wideTextNodes[4].InnerText = storeCount.ToString();
+ wideTextNodes[5].InnerText = "Stores";
+
+ var wideBindingElement = wideTileXml.GetElementsByTagName("binding")[0];
+ var importedNode = narrowTileXml.ImportNode(wideBindingElement, true);
+ narrowTileXml.GetElementsByTagName("visual")[0].AppendChild(importedNode);
+
+ for (int i = 0; i < 5; i++) {
+ TileUpdateManager.CreateTileUpdaterForApplication()
+ .Update(new TileNotification(narrowTileXml));
+ }
+ }
+
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+ viewModel = (ViewModel)e.Parameter;
+ this.DataContext = viewModel;
+
+ MainFrame.Navigate(typeof(ListPage), viewModel);
+
+ viewModel.GroceryList.CollectionChanged += (sender, args) => {
+ UpdateTile();
+ UpdateBadge();
+ };
+
+ UpdateTile();
+ UpdateBadge();
+ }
+
+ private void NavBarButtonPress(object sender, RoutedEventArgs e) {
+ Boolean isListView = (Button)sender == ListViewButton;
+ MainFrame.Navigate(isListView ? typeof(ListPage)
+ : typeof(DetailPage), viewModel);
+
+ }
+ }
+}
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml
new file mode 100644
index 0000000..484abad
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml.cs b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml.cs
new file mode 100644
index 0000000..65510c8
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Pages/NoItemSelected.xaml.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+using Windows.UI.Xaml.Data;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Navigation;
+
+// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
+
+namespace GrocerApp.Pages {
+ ///
+ /// An empty page that can be used on its own or navigated to within a Frame.
+ ///
+ public sealed partial class NoItemSelected : Page {
+ public NoItemSelected() {
+ this.InitializeComponent();
+ }
+
+ ///
+ /// Invoked when this page is about to be displayed in a Frame.
+ ///
+ /// Event data that describes how this page was reached. The Parameter
+ /// property is typically used to configure the page.
+ protected override void OnNavigatedTo(NavigationEventArgs e) {
+ }
+ }
+}
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Properties/AssemblyInfo.cs b/Source Code/Chapter 5/GrocerApp/GrocerApp/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..f2e348e
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Properties/AssemblyInfo.cs
@@ -0,0 +1,29 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("GrocerApp")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("GrocerApp")]
+[assembly: AssemblyCopyright("Copyright © 2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/Source Code/Chapter 5/GrocerApp/GrocerApp/Resources/GrocerResourceDictionary.xaml b/Source Code/Chapter 5/GrocerApp/GrocerApp/Resources/GrocerResourceDictionary.xaml
new file mode 100644
index 0000000..40867bb
--- /dev/null
+++ b/Source Code/Chapter 5/GrocerApp/GrocerApp/Resources/GrocerResourceDictionary.xaml
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/contributing.md b/contributing.md
new file mode 100644
index 0000000..f6005ad
--- /dev/null
+++ b/contributing.md
@@ -0,0 +1,14 @@
+# Contributing to Apress Source Code
+
+Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers.
+
+## How to Contribute
+
+1. Make sure you have a GitHub account.
+2. Fork the repository for the relevant book.
+3. Create a new branch on which to make your change, e.g.
+`git checkout -b my_code_contribution`
+4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted.
+5. Submit a pull request.
+
+Thank you for your contribution!
\ No newline at end of file