Procházet zdrojové kódy

Update TripExpense to use new features

James Montemagno před 10 roky
rodič
revize
697a951ce1
41 změnil soubory, kde provedl 727 přidání a 615 odebrání
  1. 0 22
      Demos/TripExpenses/.gitattributes
  2. 0 217
      Demos/TripExpenses/.gitignore
  3. 0 6
      Demos/TripExpenses/.nuget/NuGet.Config
  4. binární
      Demos/TripExpenses/.nuget/NuGet.exe
  5. 0 144
      Demos/TripExpenses/.nuget/NuGet.targets
  6. 6 2
      Demos/TripExpenses/README.md
  7. 25 0
      Demos/TripExpenses/TripExpenses.UI/Converters/MultiTriggerConverter.cs
  8. 12 0
      Demos/TripExpenses/TripExpenses.UI/MyClass.cs
  9. 27 0
      Demos/TripExpenses/TripExpenses.UI/Properties/AssemblyInfo.cs
  10. 62 0
      Demos/TripExpenses/TripExpenses.UI/TripExpenses.UI.csproj
  11. 4 0
      Demos/TripExpenses/TripExpenses.UI/packages.config
  12. 129 56
      Demos/TripExpenses/TripExpenses.sln
  13. 15 0
      Demos/TripExpenses/TripExpenses.userprefs
  14. 5 1
      Demos/TripExpenses/TripExpenses/TripExpenses.Android/Properties/AndroidManifest.xml
  15. 19 12
      Demos/TripExpenses/TripExpenses/TripExpenses.Android/Resources/Resource.Designer.cs
  16. binární
      Demos/TripExpenses/TripExpenses/TripExpenses.Android/Resources/drawable-hdpi/add.png
  17. binární
      Demos/TripExpenses/TripExpenses/TripExpenses.Android/Resources/drawable-mdpi/add.png
  18. binární
      Demos/TripExpenses/TripExpenses/TripExpenses.Android/Resources/drawable-xhdpi/add.png
  19. binární
      Demos/TripExpenses/TripExpenses/TripExpenses.Android/Resources/drawable-xxhdpi/add.png
  20. 47 43
      Demos/TripExpenses/TripExpenses/TripExpenses.Android/TripExpenses.Android.csproj
  21. 2 0
      Demos/TripExpenses/TripExpenses/TripExpenses.Android/packages.config
  22. 27 5
      Demos/TripExpenses/TripExpenses/TripExpenses.WinPhone/TripExpenses.WinPhone.csproj
  23. binární
      Demos/TripExpenses/TripExpenses/TripExpenses.WinPhone/add.png
  24. 2 0
      Demos/TripExpenses/TripExpenses/TripExpenses.WinPhone/packages.config
  25. binární
      Demos/TripExpenses/TripExpenses/TripExpenses.iOS/Resources/add.png
  26. binární
      Demos/TripExpenses/TripExpenses/TripExpenses.iOS/Resources/add@2x.png
  27. binární
      Demos/TripExpenses/TripExpenses/TripExpenses.iOS/Resources/add@3x.png
  28. 45 43
      Demos/TripExpenses/TripExpenses/TripExpenses.iOS/TripExpenses.iOS.csproj
  29. 2 0
      Demos/TripExpenses/TripExpenses/TripExpenses.iOS/packages.config
  30. 18 0
      Demos/TripExpenses/TripExpenses/TripExpenses/Interfaces/IDataStore.cs
  31. 11 1
      Demos/TripExpenses/TripExpenses/TripExpenses/Models/TripExpense.cs
  32. 27 13
      Demos/TripExpenses/TripExpenses/TripExpenses/Services/AzureDataStore.cs
  33. 132 0
      Demos/TripExpenses/TripExpenses/TripExpenses/Services/XMLDataStore.cs
  34. 6 3
      Demos/TripExpenses/TripExpenses/TripExpenses/TripExpenses.Shared.projitems
  35. 2 2
      Demos/TripExpenses/TripExpenses/TripExpenses/TripExpenses.Shared.shproj
  36. 5 3
      Demos/TripExpenses/TripExpenses/TripExpenses/ViewModels/DetailViewModel.cs
  37. 43 3
      Demos/TripExpenses/TripExpenses/TripExpenses/ViewModels/ExpensesViewModel.cs
  38. 14 5
      Demos/TripExpenses/TripExpenses/TripExpenses/Views/DetailsPage.xaml
  39. 3 1
      Demos/TripExpenses/TripExpenses/TripExpenses/Views/DetailsPage.xaml.cs
  40. 25 21
      Demos/TripExpenses/TripExpenses/TripExpenses/Views/ExpenseListPage.xaml
  41. 12 12
      Demos/TripExpenses/TripExpenses/TripExpenses/Views/ExpenseListPage.xaml.cs

+ 0 - 22
Demos/TripExpenses/.gitattributes

@@ -1,22 +0,0 @@
-# Auto detect text files and perform LF normalization
-* text=auto
-
-# Custom for Visual Studio
-*.cs     diff=csharp
-*.sln    merge=union
-*.csproj merge=union
-*.vbproj merge=union
-*.fsproj merge=union
-*.dbproj merge=union
-
-# Standard to msysgit
-*.doc	 diff=astextplain
-*.DOC	 diff=astextplain
-*.docx diff=astextplain
-*.DOCX diff=astextplain
-*.dot  diff=astextplain
-*.DOT  diff=astextplain
-*.pdf  diff=astextplain
-*.PDF	 diff=astextplain
-*.rtf	 diff=astextplain
-*.RTF	 diff=astextplain

+ 0 - 217
Demos/TripExpenses/.gitignore

@@ -1,217 +0,0 @@
-#################
-## Eclipse
-#################
-
-*.pydevproject
-.project
-.metadata
-bin/
-tmp/
-*.tmp
-*.bak
-*.swp
-*~.nib
-local.properties
-.classpath
-.settings/
-.loadpath
-
-# External tool builders
-.externalToolBuilders/
-
-# Locally stored "Eclipse launch configurations"
-*.launch
-
-# CDT-specific
-.cproject
-
-# PDT-specific
-.buildpath
-
-
-#################
-## Visual Studio
-#################
-
-## Ignore Visual Studio temporary files, build results, and
-## files generated by popular Visual Studio add-ons.
-
-# User-specific files
-*.suo
-*.user
-*.sln.docstates
-
-# Build results
-
-[Dd]ebug/
-[Rr]elease/
-x64/
-build/
-[Bb]in/
-[Oo]bj/
-[Pp]ackages/
-[Cc]omponents/
-
-# MSTest test Results
-[Tt]est[Rr]esult*/
-[Bb]uild[Ll]og.*
-
-*_i.c
-*_p.c
-*.ilk
-*.meta
-*.obj
-*.pch
-*.pdb
-*.pgc
-*.pgd
-*.rsp
-*.sbr
-*.tlb
-*.tli
-*.tlh
-*.tmp
-*.tmp_proj
-*.log
-*.vspscc
-*.vssscc
-.builds
-*.pidb
-*.log
-*.scc
-
-# Visual C++ cache files
-ipch/
-*.aps
-*.ncb
-*.opensdf
-*.sdf
-*.cachefile
-
-# Visual Studio profiler
-*.psess
-*.vsp
-*.vspx
-
-# Guidance Automation Toolkit
-*.gpState
-
-# ReSharper is a .NET coding add-in
-_ReSharper*/
-*.[Rr]e[Ss]harper
-
-# TeamCity is a build add-in
-_TeamCity*
-
-# DotCover is a Code Coverage Tool
-*.dotCover
-
-# NCrunch
-*.ncrunch*
-.*crunch*.local.xml
-
-# Installshield output folder
-[Ee]xpress/
-
-# DocProject is a documentation generator add-in
-DocProject/buildhelp/
-DocProject/Help/*.HxT
-DocProject/Help/*.HxC
-DocProject/Help/*.hhc
-DocProject/Help/*.hhk
-DocProject/Help/*.hhp
-DocProject/Help/Html2
-DocProject/Help/html
-
-# Click-Once directory
-publish/
-
-# Publish Web Output
-*.Publish.xml
-*.pubxml
-
-# NuGet Packages Directory
-## TODO: If you have NuGet Package Restore enabled, uncomment the next line
-#packages/
-
-# Windows Azure Build Output
-csx
-*.build.csdef
-
-# Windows Store app package directory
-AppPackages/
-
-# Others
-sql/
-*.Cache
-ClientBin/
-[Ss]tyle[Cc]op.*
-~$*
-*~
-*.dbmdl
-*.[Pp]ublish.xml
-*.pfx
-*.publishsettings
-
-# RIA/Silverlight projects
-Generated_Code/
-
-# Backup & report files from converting an old project file to a newer
-# Visual Studio version. Backup files are not needed, because we have git ;-)
-_UpgradeReport_Files/
-Backup*/
-UpgradeLog*.XML
-UpgradeLog*.htm
-
-# SQL Server files
-App_Data/*.mdf
-App_Data/*.ldf
-
-#############
-## Windows detritus
-#############
-
-# Windows image file caches
-Thumbs.db
-ehthumbs.db
-
-# Folder config file
-Desktop.ini
-
-# Recycle Bin used on file shares
-$RECYCLE.BIN/
-
-# Mac crap
-.DS_Store
-
-
-#############
-## Python
-#############
-
-*.py[co]
-
-# Packages
-*.egg
-*.egg-info
-dist/
-build/
-eggs/
-parts/
-var/
-sdist/
-develop-eggs/
-.installed.cfg
-
-# Installer logs
-pip-log.txt
-
-# Unit test / coverage reports
-.coverage
-.tox
-
-#Translations
-*.mo
-
-#Mr Developer
-.mr.developer.cfg

+ 0 - 6
Demos/TripExpenses/.nuget/NuGet.Config

@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-  <solution>
-    <add key="disableSourceControlIntegration" value="true" />
-  </solution>
-</configuration>

binární
Demos/TripExpenses/.nuget/NuGet.exe


+ 0 - 144
Demos/TripExpenses/.nuget/NuGet.targets

@@ -1,144 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-    <PropertyGroup>
-        <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">$(MSBuildProjectDirectory)\..\</SolutionDir>
-
-        <!-- Enable the restore command to run before builds -->
-        <RestorePackages Condition="  '$(RestorePackages)' == '' ">false</RestorePackages>
-
-        <!-- Property that enables building a package from a project -->
-        <BuildPackage Condition=" '$(BuildPackage)' == '' ">false</BuildPackage>
-
-        <!-- Determines if package restore consent is required to restore packages -->
-        <RequireRestoreConsent Condition=" '$(RequireRestoreConsent)' != 'false' ">true</RequireRestoreConsent>
-
-        <!-- Download NuGet.exe if it does not already exist -->
-        <DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">false</DownloadNuGetExe>
-    </PropertyGroup>
-
-    <ItemGroup Condition=" '$(PackageSources)' == '' ">
-        <!-- Package sources used to restore packages. By default, registered sources under %APPDATA%\NuGet\NuGet.Config will be used -->
-        <!-- The official NuGet package source (https://www.nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->
-        <!--
-            <PackageSource Include="https://www.nuget.org/api/v2/" />
-            <PackageSource Include="https://my-nuget-source/nuget/" />
-        -->
-    </ItemGroup>
-
-    <PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
-        <!-- Windows specific commands -->
-        <NuGetToolsPath>$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))</NuGetToolsPath>
-    </PropertyGroup>
-
-    <PropertyGroup Condition=" '$(OS)' != 'Windows_NT'">
-        <!-- We need to launch nuget.exe with the mono command if we're not on windows -->
-        <NuGetToolsPath>$(SolutionDir).nuget</NuGetToolsPath>
-    </PropertyGroup>
-
-    <PropertyGroup>
-        <PackagesProjectConfig Condition=" '$(OS)' == 'Windows_NT'">$(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config</PackagesProjectConfig>
-        <PackagesProjectConfig Condition=" '$(OS)' != 'Windows_NT'">$(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config</PackagesProjectConfig>
-    </PropertyGroup>
-
-    <PropertyGroup>
-      <PackagesConfig Condition="Exists('$(MSBuildProjectDirectory)\packages.config')">$(MSBuildProjectDirectory)\packages.config</PackagesConfig>
-      <PackagesConfig Condition="Exists('$(PackagesProjectConfig)')">$(PackagesProjectConfig)</PackagesConfig>
-    </PropertyGroup>
-    
-    <PropertyGroup>
-        <!-- NuGet command -->
-        <NuGetExePath Condition=" '$(NuGetExePath)' == '' ">$(NuGetToolsPath)\NuGet.exe</NuGetExePath>
-        <PackageSources Condition=" $(PackageSources) == '' ">@(PackageSource)</PackageSources>
-
-        <NuGetCommand Condition=" '$(OS)' == 'Windows_NT'">"$(NuGetExePath)"</NuGetCommand>
-        <NuGetCommand Condition=" '$(OS)' != 'Windows_NT' ">mono --runtime=v4.0.30319 "$(NuGetExePath)"</NuGetCommand>
-
-        <PackageOutputDir Condition="$(PackageOutputDir) == ''">$(TargetDir.Trim('\\'))</PackageOutputDir>
-
-        <RequireConsentSwitch Condition=" $(RequireRestoreConsent) == 'true' ">-RequireConsent</RequireConsentSwitch>
-        <NonInteractiveSwitch Condition=" '$(VisualStudioVersion)' != '' AND '$(OS)' == 'Windows_NT' ">-NonInteractive</NonInteractiveSwitch>
-
-        <PaddedSolutionDir Condition=" '$(OS)' == 'Windows_NT'">"$(SolutionDir) "</PaddedSolutionDir>
-        <PaddedSolutionDir Condition=" '$(OS)' != 'Windows_NT' ">"$(SolutionDir)"</PaddedSolutionDir>
-
-        <!-- Commands -->
-        <RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)"  $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)</RestoreCommand>
-        <BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols</BuildCommand>
-
-        <!-- We need to ensure packages are restored prior to assembly resolve -->
-        <BuildDependsOn Condition="$(RestorePackages) == 'true'">
-            RestorePackages;
-            $(BuildDependsOn);
-        </BuildDependsOn>
-
-        <!-- Make the build depend on restore packages -->
-        <BuildDependsOn Condition="$(BuildPackage) == 'true'">
-            $(BuildDependsOn);
-            BuildPackage;
-        </BuildDependsOn>
-    </PropertyGroup>
-
-    <Target Name="CheckPrerequisites">
-        <!-- Raise an error if we're unable to locate nuget.exe  -->
-        <Error Condition="'$(DownloadNuGetExe)' != 'true' AND !Exists('$(NuGetExePath)')" Text="Unable to locate '$(NuGetExePath)'" />
-        <!--
-        Take advantage of MsBuild's build dependency tracking to make sure that we only ever download nuget.exe once.
-        This effectively acts as a lock that makes sure that the download operation will only happen once and all
-        parallel builds will have to wait for it to complete.
-        -->
-        <MsBuild Targets="_DownloadNuGet" Projects="$(MSBuildThisFileFullPath)" Properties="Configuration=NOT_IMPORTANT;DownloadNuGetExe=$(DownloadNuGetExe)" />
-    </Target>
-
-    <Target Name="_DownloadNuGet">
-        <DownloadNuGet OutputFilename="$(NuGetExePath)" Condition=" '$(DownloadNuGetExe)' == 'true' AND !Exists('$(NuGetExePath)')" />
-    </Target>
-
-    <Target Name="RestorePackages" DependsOnTargets="CheckPrerequisites">        
-        <Exec Command="$(RestoreCommand)"
-              Condition="'$(OS)' != 'Windows_NT' And Exists('$(PackagesConfig)')" />
-
-        <Exec Command="$(RestoreCommand)"
-              LogStandardErrorAsError="true"
-              Condition="'$(OS)' == 'Windows_NT' And Exists('$(PackagesConfig)')" />
-    </Target>
-
-    <Target Name="BuildPackage" DependsOnTargets="CheckPrerequisites">
-        <Exec Command="$(BuildCommand)"
-              Condition=" '$(OS)' != 'Windows_NT' " />
-
-        <Exec Command="$(BuildCommand)"
-              LogStandardErrorAsError="true"
-              Condition=" '$(OS)' == 'Windows_NT' " />
-    </Target>
-
-    <UsingTask TaskName="DownloadNuGet" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
-        <ParameterGroup>
-            <OutputFilename ParameterType="System.String" Required="true" />
-        </ParameterGroup>
-        <Task>
-            <Reference Include="System.Core" />
-            <Using Namespace="System" />
-            <Using Namespace="System.IO" />
-            <Using Namespace="System.Net" />
-            <Using Namespace="Microsoft.Build.Framework" />
-            <Using Namespace="Microsoft.Build.Utilities" />
-            <Code Type="Fragment" Language="cs">
-                <![CDATA[
-                try {
-                    OutputFilename = Path.GetFullPath(OutputFilename);
-
-                    Log.LogMessage("Downloading latest version of NuGet.exe...");
-                    WebClient webClient = new WebClient();
-                    webClient.DownloadFile("https://www.nuget.org/nuget.exe", OutputFilename);
-
-                    return true;
-                }
-                catch (Exception ex) {
-                    Log.LogErrorFromException(ex);
-                    return false;
-                }
-            ]]>
-            </Code>
-        </Task>
-    </UsingTask>
-</Project>

+ 6 - 2
Demos/TripExpenses/README.md

@@ -1,13 +1,17 @@
-Xamarin.Forms-TripExpenses-TechEd
+Xamarin.Forms-TripExpenses
 ==========================
 
 Xamarin.Forms Azure Demo of a simple expense app with Azure Mobile Services online and offline sync with a backed SQLite database for iOS, Android, and Windows Phone.
 
 ##Setup
 
+* By default TripExpenses uses a cross-platform Json Based file system, however you can add Azure Mobile Services easily by following:
+
 * Signup for an Azure Mobile Services account: http://azure.microsoft.com/en-us/services/mobile-services/
+* Open: XMLDataStore.cs and comment OUT the [assemby:Dependency()] flag
 * Create a new Azure Mobile Services Table Called "TripExpense"
-* Open "DataStore.cs" in TripExpenses shared project
+* Open “AzureDataStore.cs" in TripExpenses shared project
+* Comment IN the [assemby:Dependency()] flag
 * Edit: MobileService = new MobileServiceClient(
         "https://"+"PUT-SITE-HERE" +".azure-mobile.net/",
         "PUT-YOUR-API-KEY-HERE");

+ 25 - 0
Demos/TripExpenses/TripExpenses.UI/Converters/MultiTriggerConverter.cs

@@ -0,0 +1,25 @@
+using System;
+using Xamarin.Forms;
+using System.Globalization;
+
+namespace TripExpenses.UI
+{
+	public class MultiTriggerConverter : IValueConverter
+	{
+		public object Convert(object value, Type targetType,
+			object parameter, CultureInfo culture)
+		{
+			if ((int)value > 0) // length > 0 ?
+				return true;            // some data has been entered
+			else
+				return false;           // input is empty
+		}
+
+		public object ConvertBack(object value, Type targetType,
+			object parameter, CultureInfo culture)
+		{
+			throw new NotSupportedException ();
+		}
+	}
+}
+

+ 12 - 0
Demos/TripExpenses/TripExpenses.UI/MyClass.cs

@@ -0,0 +1,12 @@
+using System;
+
+namespace TripExpenses.UI
+{
+	public class MyClass
+	{
+		public MyClass ()
+		{
+		}
+	}
+}
+

+ 27 - 0
Demos/TripExpenses/TripExpenses.UI/Properties/AssemblyInfo.cs

@@ -0,0 +1,27 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle ("TripExpenses.UI")]
+[assembly: AssemblyDescription ("")]
+[assembly: AssemblyConfiguration ("")]
+[assembly: AssemblyCompany ("")]
+[assembly: AssemblyProduct ("")]
+[assembly: AssemblyCopyright ("jamesmontemagno")]
+[assembly: AssemblyTrademark ("")]
+[assembly: AssemblyCulture ("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion ("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+

+ 62 - 0
Demos/TripExpenses/TripExpenses.UI/TripExpenses.UI.csproj

@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <ProjectGuid>{E1DF5355-B3F1-4991-A022-897C33DD29DB}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>TripExpenses.UI</RootNamespace>
+    <AssemblyName>TripExpenses.UI</AssemblyName>
+    <TargetFrameworkProfile>Profile78</TargetFrameworkProfile>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
+    <RestorePackages>true</RestorePackages>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Converters\MultiTriggerConverter.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
+  <Import Project="..\packages\Xamarin.Forms.1.4.2.6359\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.targets" Condition="Exists('..\packages\Xamarin.Forms.1.4.2.6359\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.targets')" />
+  <ItemGroup />
+  <ItemGroup>
+    <Reference Include="Xamarin.Forms.Core">
+      <HintPath>..\packages\Xamarin.Forms.1.4.2.6359\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Xamarin.Forms.Xaml">
+      <HintPath>..\packages\Xamarin.Forms.1.4.2.6359\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Xaml.dll</HintPath>
+    </Reference>
+    <Reference Include="Xamarin.Forms.Platform">
+      <HintPath>..\packages\Xamarin.Forms.1.4.2.6359\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Platform.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
+  </Target>
+</Project>

+ 4 - 0
Demos/TripExpenses/TripExpenses.UI/packages.config

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Xamarin.Forms" version="1.4.2.6359" targetFramework="portable-net45+win+wp80+MonoTouch10+MonoAndroid10+xamarinmac20+xamarinios10" />
+</packages>

+ 129 - 56
Demos/TripExpenses/TripExpenses.sln

@@ -1,15 +1,9 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.30501.0
+# Visual Studio 2012
+VisualStudioVersion = 12.0.31101.0
 MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TripExpenses.WinPhone", "TripExpenses\TripExpenses.WinPhone\TripExpenses.WinPhone.csproj", "{76F43AAB-2104-4A36-95B0-10C8390D01A6}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TripExpenses.iOS", "TripExpenses\TripExpenses.iOS\TripExpenses.iOS.csproj", "{D6028D44-6FAD-4A97-A934-90435BAB207A}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TripExpenses.Android", "TripExpenses\TripExpenses.Android\TripExpenses.Android.csproj", "{5FDE5A98-2438-421B-8A34-DAEC90C549EA}"
-EndProject
-Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "TripExpenses", "TripExpenses\TripExpenses\TripExpenses.shproj", "{908B9AB7-C998-4B59-B85E-EC37794FB92B}"
+Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "TripExpenses.Shared", "TripExpenses\TripExpenses\TripExpenses.Shared.shproj", "{908B9AB7-C998-4B59-B85E-EC37794FB92B}"
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{08A004CC-1F41-4F11-9F6E-3A3339642151}"
 	ProjectSection(SolutionItems) = preProject
@@ -18,13 +12,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{08A004
 		.nuget\NuGet.targets = .nuget\NuGet.targets
 	EndProjectSection
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TripExpenses.UI", "TripExpenses.UI\TripExpenses.UI.csproj", "{E1DF5355-B3F1-4991-A022-897C33DD29DB}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platforms", "Platforms", "{585B80C2-8D3B-4AE6-AE23-F26FC3A93F9F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TripExpenses.Android", "TripExpenses\TripExpenses.Android\TripExpenses.Android.csproj", "{5FDE5A98-2438-421B-8A34-DAEC90C549EA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TripExpenses.iOS", "TripExpenses\TripExpenses.iOS\TripExpenses.iOS.csproj", "{D6028D44-6FAD-4A97-A934-90435BAB207A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TripExpenses.WinPhone", "TripExpenses\TripExpenses.WinPhone\TripExpenses.WinPhone.csproj", "{76F43AAB-2104-4A36-95B0-10C8390D01A6}"
+EndProject
 Global
-	GlobalSection(SharedMSBuildProjectFiles) = preSolution
-		TripExpenses\TripExpenses\TripExpenses.projitems*{5fde5a98-2438-421b-8a34-daec90c549ea}*SharedItemsImports = 4
-		TripExpenses\TripExpenses\TripExpenses.projitems*{908b9ab7-c998-4b59-b85e-ec37794fb92b}*SharedItemsImports = 13
-		TripExpenses\TripExpenses\TripExpenses.projitems*{d6028d44-6fad-4a97-a934-90435bab207a}*SharedItemsImports = 4
-		TripExpenses\TripExpenses\TripExpenses.projitems*{76f43aab-2104-4a36-95b0-10c8390d01a6}*SharedItemsImports = 4
-	EndGlobalSection
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
 		Ad-Hoc|ARM = Ad-Hoc|ARM
@@ -52,6 +50,46 @@ Global
 		Release|x86 = Release|x86
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|Mixed Platforms.Build.0 = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|Mixed Platforms.Deploy.0 = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|Any CPU.Build.0 = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|Any CPU.Deploy.0 = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|ARM.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|iPhone.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|Mixed Platforms.Build.0 = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|Mixed Platforms.Deploy.0 = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|x86.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|ARM.ActiveCfg = Debug|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|Any CPU.Build.0 = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|Any CPU.Deploy.0 = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|ARM.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|x86.ActiveCfg = Release|Any CPU
 		{76F43AAB-2104-4A36-95B0-10C8390D01A6}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
 		{76F43AAB-2104-4A36-95B0-10C8390D01A6}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
 		{76F43AAB-2104-4A36-95B0-10C8390D01A6}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU
@@ -132,7 +170,8 @@ Global
 		{D6028D44-6FAD-4A97-A934-90435BAB207A}.AppStore|Mixed Platforms.Build.0 = AppStore|iPhone
 		{D6028D44-6FAD-4A97-A934-90435BAB207A}.AppStore|Mixed Platforms.Deploy.0 = AppStore|iPhone
 		{D6028D44-6FAD-4A97-A934-90435BAB207A}.AppStore|x86.ActiveCfg = AppStore|iPhone
-		{D6028D44-6FAD-4A97-A934-90435BAB207A}.Debug|Any CPU.ActiveCfg = Debug|iPhone
+		{D6028D44-6FAD-4A97-A934-90435BAB207A}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator
+		{D6028D44-6FAD-4A97-A934-90435BAB207A}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator
 		{D6028D44-6FAD-4A97-A934-90435BAB207A}.Debug|ARM.ActiveCfg = Debug|iPhone
 		{D6028D44-6FAD-4A97-A934-90435BAB207A}.Debug|iPhone.ActiveCfg = Debug|iPhone
 		{D6028D44-6FAD-4A97-A934-90435BAB207A}.Debug|iPhone.Build.0 = Debug|iPhone
@@ -156,46 +195,80 @@ Global
 		{D6028D44-6FAD-4A97-A934-90435BAB207A}.Release|Mixed Platforms.Build.0 = Release|iPhone
 		{D6028D44-6FAD-4A97-A934-90435BAB207A}.Release|Mixed Platforms.Deploy.0 = Release|iPhone
 		{D6028D44-6FAD-4A97-A934-90435BAB207A}.Release|x86.ActiveCfg = Release|iPhone
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|Mixed Platforms.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|Mixed Platforms.Build.0 = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|Mixed Platforms.Deploy.0 = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|Any CPU.Build.0 = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|Any CPU.Deploy.0 = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|ARM.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|Mixed Platforms.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|Mixed Platforms.Build.0 = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|Mixed Platforms.Deploy.0 = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.AppStore|x86.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|ARM.ActiveCfg = Debug|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Debug|x86.ActiveCfg = Debug|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|Any CPU.Build.0 = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|Any CPU.Deploy.0 = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|ARM.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
-		{5FDE5A98-2438-421B-8A34-DAEC90C549EA}.Release|x86.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Ad-Hoc|ARM.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Ad-Hoc|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Ad-Hoc|Mixed Platforms.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Ad-Hoc|x86.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.AppStore|Any CPU.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.AppStore|ARM.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.AppStore|ARM.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.AppStore|iPhone.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.AppStore|iPhone.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.AppStore|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.AppStore|Mixed Platforms.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.AppStore|x86.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.AppStore|x86.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Debug|ARM.ActiveCfg = Debug|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Debug|ARM.Build.0 = Debug|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Debug|x86.Build.0 = Debug|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Release|ARM.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Release|ARM.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Release|iPhone.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Release|x86.ActiveCfg = Release|Any CPU
+		{E1DF5355-B3F1-4991-A022-897C33DD29DB}.Release|x86.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(NestedProjects) = preSolution
+		{5FDE5A98-2438-421B-8A34-DAEC90C549EA} = {585B80C2-8D3B-4AE6-AE23-F26FC3A93F9F}
+		{D6028D44-6FAD-4A97-A934-90435BAB207A} = {585B80C2-8D3B-4AE6-AE23-F26FC3A93F9F}
+		{76F43AAB-2104-4A36-95B0-10C8390D01A6} = {585B80C2-8D3B-4AE6-AE23-F26FC3A93F9F}
+	EndGlobalSection
+	GlobalSection(MonoDevelopProperties) = preSolution
+		Policies = $0
+		$0.TextStylePolicy = $1
+		$1.FileWidth = 120
+		$1.TabWidth = 2
+		$1.IndentWidth = 2
+		$1.inheritsSet = Mono
+		$1.inheritsScope = text/plain
+		$1.scope = text/x-csharp
+		$0.CSharpFormattingPolicy = $2
+		$2.AfterDelegateDeclarationParameterComma = True
+		$2.inheritsSet = Mono
+		$2.inheritsScope = text/x-csharp
+		$2.scope = text/x-csharp
+	EndGlobalSection
+	GlobalSection(SharedMSBuildProjectFiles) = preSolution
+		TripExpenses\TripExpenses\TripExpenses.Shared.projitems*{5fde5a98-2438-421b-8a34-daec90c549ea}*SharedItemsImports = 4
+		TripExpenses\TripExpenses\TripExpenses.Shared.projitems*{908b9ab7-c998-4b59-b85e-ec37794fb92b}*SharedItemsImports = 13
+		TripExpenses\TripExpenses\TripExpenses.Shared.projitems*{d6028d44-6fad-4a97-a934-90435bab207a}*SharedItemsImports = 4
+		TripExpenses\TripExpenses\TripExpenses.Shared.projitems*{76f43aab-2104-4a36-95b0-10c8390d01a6}*SharedItemsImports = 4
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 15 - 0
Demos/TripExpenses/TripExpenses.userprefs

@@ -0,0 +1,15 @@
+<Properties StartupItem="TripExpenses/TripExpenses.iOS/TripExpenses.iOS.csproj">
+  <MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" PreferredExecutionTarget="Android.Nexus 4 (Lollipop)" />
+  <MonoDevelop.Ide.Workbench ActiveDocument="TripExpenses/TripExpenses/Views/ExpenseListPage.xaml">
+    <Files>
+      <File FileName="TripExpenses/TripExpenses/Services/AzureDataStore.cs" Line="1" Column="1" />
+      <File FileName="TripExpenses/TripExpenses/Services/XMLDataStore.cs" Line="1" Column="1" />
+      <File FileName="TripExpenses/TripExpenses/Views/ExpenseListPage.xaml" Line="22" Column="23" />
+      <File FileName="TripExpenses/TripExpenses/Views/DetailsPage.xaml" Line="1" Column="1" />
+    </Files>
+  </MonoDevelop.Ide.Workbench>
+  <MonoDevelop.Ide.DebuggingService.Breakpoints>
+    <BreakpointStore />
+  </MonoDevelop.Ide.DebuggingService.Breakpoints>
+  <MonoDevelop.Ide.DebuggingService.PinnedWatches />
+</Properties>

+ 5 - 1
Demos/TripExpenses/TripExpenses/TripExpenses.Android/Properties/AndroidManifest.xml

@@ -1,5 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android">
 	<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="21" />
-	<application android:theme="@android:style/Theme.Holo.Light"></application>
+	<application android:theme="@android:style/Theme.Holo.Light">
+	</application>
+	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+	<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+	<uses-permission android:name="android.permission.INTERNET" />
 </manifest>

+ 19 - 12
Demos/TripExpenses/TripExpenses/TripExpenses.Android/Resources/Resource.Designer.cs

@@ -1,15 +1,15 @@
 #pragma warning disable 1591
-//------------------------------------------------------------------------------
-// <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:4.0.30319.34014
-//
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
-// </auto-generated>
-//------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------
+//  <autogenerated>
+//      This code was generated by a tool.
+//      Mono Runtime Version: 4.0.30319.17020
+// 
+//      Changes to this file may cause incorrect behavior and will be lost if 
+//      the code is regenerated.
+//  </autogenerated>
+// ------------------------------------------------------------------------------
 
-[assembly: global::Android.Runtime.ResourceDesignerAttribute("TripExpenses.Droid.Resource", IsApplication=true)]
+[assembly: Android.Runtime.ResourceDesignerAttribute("TripExpenses.Droid.Resource", IsApplication=true)]
 
 namespace TripExpenses.Droid
 {
@@ -28,6 +28,10 @@ namespace TripExpenses.Droid
 		{
 			global::Xamarin.Forms.Platform.Resource.String.ApplicationName = global::TripExpenses.Droid.Resource.String.ApplicationName;
 			global::Xamarin.Forms.Platform.Resource.String.Hello = global::TripExpenses.Droid.Resource.String.Hello;
+			global::PCLStorage.Resource.String.ApplicationName = global::TripExpenses.Droid.Resource.String.ApplicationName;
+			global::PCLStorage.Resource.String.Hello = global::TripExpenses.Droid.Resource.String.Hello;
+			global::Refractored.Xam.TTS.Resource.String.ApplicationName = global::TripExpenses.Droid.Resource.String.ApplicationName;
+			global::Refractored.Xam.TTS.Resource.String.Hello = global::TripExpenses.Droid.Resource.String.Hello;
 		}
 		
 		public partial class Attribute
@@ -47,10 +51,13 @@ namespace TripExpenses.Droid
 		{
 			
 			// aapt resource value: 0x7f020000
-			public const int Icon = 2130837504;
+			public const int add = 2130837504;
 			
 			// aapt resource value: 0x7f020001
-			public const int refresh = 2130837505;
+			public const int Icon = 2130837505;
+			
+			// aapt resource value: 0x7f020002
+			public const int refresh = 2130837506;
 			
 			static Drawable()
 			{

binární
Demos/TripExpenses/TripExpenses/TripExpenses.Android/Resources/drawable-hdpi/add.png


binární
Demos/TripExpenses/TripExpenses/TripExpenses.Android/Resources/drawable-mdpi/add.png


binární
Demos/TripExpenses/TripExpenses/TripExpenses.Android/Resources/drawable-xhdpi/add.png


binární
Demos/TripExpenses/TripExpenses/TripExpenses.Android/Resources/drawable-xxhdpi/add.png


+ 47 - 43
Demos/TripExpenses/TripExpenses/TripExpenses.Android/TripExpenses.Android.csproj

@@ -3,8 +3,6 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>8.0.30703</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{5FDE5A98-2438-421B-8A34-DAEC90C549EA}</ProjectGuid>
     <ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
     <OutputType>Library</OutputType>
@@ -21,9 +19,9 @@
     <AndroidSupportedAbis>armeabi,armeabi-v7a,x86</AndroidSupportedAbis>
     <AndroidStoreUncompressedFileExtensions />
     <MandroidI18n />
-    <JavaMaximumHeapSize />
+    <JavaMaximumHeapSize>
+    </JavaMaximumHeapSize>
     <JavaOptions />
-    <AndroidUseLatestPlatformSdk />
     <NuGetPackageImportStamp>8ecd6661</NuGetPackageImportStamp>
     <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
     <RestorePackages>true</RestorePackages>
@@ -36,7 +34,6 @@
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
-    <AndroidUseSharedRuntime>True</AndroidUseSharedRuntime>
     <AndroidLinkMode>None</AndroidLinkMode>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
@@ -47,71 +44,68 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
-    <AndroidLinkMode>SdkOnly</AndroidLinkMode>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="FormsViewGroup, Version=1.4.0.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="Mono.Android" />
+    <Reference Include="mscorlib" />
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Xml" />
+    <Reference Include="FormsViewGroup, Version=1.4.0.0, Culture=neutral, PublicKeyToken=null">
       <HintPath>..\..\packages\Xamarin.Forms.1.4.2.6359\lib\MonoAndroid10\FormsViewGroup.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="Microsoft.WindowsAzure.Mobile, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+    <Reference Include="Microsoft.WindowsAzure.Mobile, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
       <HintPath>..\..\packages\WindowsAzure.MobileServices.1.3.2\lib\monoandroid\Microsoft.WindowsAzure.Mobile.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="Microsoft.WindowsAzure.Mobile.Ext, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+    <Reference Include="Microsoft.WindowsAzure.Mobile.Ext, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
       <HintPath>..\..\packages\WindowsAzure.MobileServices.1.3.2\lib\monoandroid\Microsoft.WindowsAzure.Mobile.Ext.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="Microsoft.WindowsAzure.Mobile.SQLiteStore, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+    <Reference Include="Microsoft.WindowsAzure.Mobile.SQLiteStore, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
       <HintPath>..\..\packages\WindowsAzure.MobileServices.SQLiteStore.1.0.4\lib\portable-win+net45+wp8+wpa81+monotouch+monoandroid\Microsoft.WindowsAzure.Mobile.SQLiteStore.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="Mono.Android" />
-    <Reference Include="mscorlib" />
-    <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+    <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
       <HintPath>..\..\packages\Newtonsoft.Json.6.0.8\lib\portable-net40+sl5+wp80+win8+wpa81\Newtonsoft.Json.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="SQLitePCL, Version=3.8.7.2, Culture=neutral, PublicKeyToken=bddade01e9c850c5, processorArchitecture=MSIL">
+    <Reference Include="SQLitePCL, Version=3.8.7.2, Culture=neutral, PublicKeyToken=bddade01e9c850c5">
       <HintPath>..\..\packages\SQLitePCL.3.8.7.2\lib\MonoAndroid\SQLitePCL.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="SQLitePCL.Ext, Version=3.8.7.2, Culture=neutral, PublicKeyToken=bddade01e9c850c5, processorArchitecture=MSIL">
+    <Reference Include="SQLitePCL.Ext, Version=3.8.7.2, Culture=neutral, PublicKeyToken=bddade01e9c850c5">
       <HintPath>..\..\packages\SQLitePCL.3.8.7.2\lib\MonoAndroid\SQLitePCL.Ext.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Net.Http" />
-    <Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+    <Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
       <HintPath>..\..\packages\Microsoft.Net.Http.2.2.29\lib\monoandroid\System.Net.Http.Extensions.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+    <Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
       <HintPath>..\..\packages\Microsoft.Net.Http.2.2.29\lib\monoandroid\System.Net.Http.Primitives.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Xml" />
-    <Reference Include="Xamarin.Android.Support.v4, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="Xamarin.Android.Support.v4, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
       <HintPath>..\..\packages\Xamarin.Android.Support.v4.22.1.1.1\lib\MonoAndroid403\Xamarin.Android.Support.v4.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="Xamarin.Forms.Core, Version=1.4.0.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="Xamarin.Forms.Core, Version=1.4.0.0, Culture=neutral, PublicKeyToken=null">
       <HintPath>..\..\packages\Xamarin.Forms.1.4.2.6359\lib\MonoAndroid10\Xamarin.Forms.Core.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="Xamarin.Forms.Platform, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="Xamarin.Forms.Platform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
       <HintPath>..\..\packages\Xamarin.Forms.1.4.2.6359\lib\MonoAndroid10\Xamarin.Forms.Platform.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="Xamarin.Forms.Platform.Android, Version=1.4.0.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="Xamarin.Forms.Platform.Android, Version=1.4.0.0, Culture=neutral, PublicKeyToken=null">
       <HintPath>..\..\packages\Xamarin.Forms.1.4.2.6359\lib\MonoAndroid10\Xamarin.Forms.Platform.Android.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="Xamarin.Forms.Xaml, Version=1.4.0.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="Xamarin.Forms.Xaml, Version=1.4.0.0, Culture=neutral, PublicKeyToken=null">
       <HintPath>..\..\packages\Xamarin.Forms.1.4.2.6359\lib\MonoAndroid10\Xamarin.Forms.Xaml.dll</HintPath>
-      <Private>True</Private>
+    </Reference>
+    <Reference Include="PCLStorage">
+      <HintPath>..\..\packages\PCLStorage.1.0.2\lib\monoandroid\PCLStorage.dll</HintPath>
+    </Reference>
+    <Reference Include="PCLStorage.Abstractions">
+      <HintPath>..\..\packages\PCLStorage.1.0.2\lib\monoandroid\PCLStorage.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Refractored.Xam.TTS.Abstractions">
+      <HintPath>..\..\packages\Xam.Plugins.TextToSpeech.1.0.1\lib\MonoAndroid10\Refractored.Xam.TTS.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Refractored.Xam.TTS">
+      <HintPath>..\..\packages\Xam.Plugins.TextToSpeech.1.0.1\lib\MonoAndroid10\Refractored.Xam.TTS.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
@@ -127,6 +121,10 @@
   </ItemGroup>
   <ItemGroup>
     <AndroidResource Include="Resources\Drawable\Icon.png" />
+    <AndroidResource Include="Resources\drawable-hdpi\add.png" />
+    <AndroidResource Include="Resources\drawable-mdpi\add.png" />
+    <AndroidResource Include="Resources\drawable-xhdpi\add.png" />
+    <AndroidResource Include="Resources\drawable-xxhdpi\add.png" />
   </ItemGroup>
   <ItemGroup>
     <Content Include="Properties\AndroidManifest.xml" />
@@ -135,8 +133,8 @@
     <AndroidResource Include="Resources\drawable-hdpi\refresh.png" />
     <AndroidResource Include="Resources\drawable-mdpi\refresh.png" />
   </ItemGroup>
-  <Import Project="..\TripExpenses\TripExpenses.projitems" Label="Shared" Condition="Exists('..\TripExpenses\TripExpenses.projitems')" />
-  <Import Project="..\TripExpenses\TripExpenses.projitems" Label="Shared" Condition="Exists('..\TripExpenses\TripExpenses.projitems')" />
+  <Import Project="..\TripExpenses\TripExpenses.Shared.projitems" Label="Shared" Condition="Exists('..\TripExpenses\TripExpenses.Shared.projitems')" />
+  <Import Project="..\TripExpenses\TripExpenses.Shared.projitems" Label="Shared" Condition="Exists('..\TripExpenses\TripExpenses.Shared.projitems')" />
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
@@ -156,4 +154,10 @@
   <Target Name="AfterBuild">
   </Target>
   -->
+  <ItemGroup>
+    <ProjectReference Include="..\..\TripExpenses.UI\TripExpenses.UI.csproj">
+      <Project>{E1DF5355-B3F1-4991-A022-897C33DD29DB}</Project>
+      <Name>TripExpenses.UI</Name>
+    </ProjectReference>
+  </ItemGroup>
 </Project>

+ 2 - 0
Demos/TripExpenses/TripExpenses/TripExpenses.Android/packages.config

@@ -4,9 +4,11 @@
   <package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="MonoAndroid44" />
   <package id="Microsoft.Net.Http" version="2.2.29" targetFramework="MonoAndroid44" />
   <package id="Newtonsoft.Json" version="6.0.8" targetFramework="MonoAndroid44" />
+  <package id="PCLStorage" version="1.0.2" targetFramework="MonoAndroid50" />
   <package id="SQLitePCL" version="3.8.7.2" targetFramework="MonoAndroid44" />
   <package id="WindowsAzure.MobileServices" version="1.3.2" targetFramework="MonoAndroid44" />
   <package id="WindowsAzure.MobileServices.SQLiteStore" version="1.0.4" targetFramework="MonoAndroid44" />
+  <package id="Xam.Plugins.TextToSpeech" version="1.0.1" targetFramework="MonoAndroid50" />
   <package id="Xamarin.Android.Support.v4" version="22.1.1.1" targetFramework="MonoAndroid44" />
   <package id="Xamarin.Forms" version="1.4.2.6359" targetFramework="MonoAndroid44" />
 </packages>

+ 27 - 5
Demos/TripExpenses/TripExpenses/TripExpenses.WinPhone/TripExpenses.WinPhone.csproj

@@ -1,11 +1,9 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="..\..\packages\SQLitePCL.3.8.7.2\build\wp8\SQLitePCL.props" Condition="Exists('..\..\packages\SQLitePCL.3.8.7.2\build\wp8\SQLitePCL.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>10.0.20506</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{76F43AAB-2104-4A36-95B0-10C8390D01A6}</ProjectGuid>
     <ProjectTypeGuids>{C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
     <OutputType>Library</OutputType>
@@ -152,6 +150,7 @@
     <Content Include="Toolkit.Content\ApplicationBar.Check.png" />
     <Content Include="Toolkit.Content\ApplicationBar.Delete.png" />
     <Content Include="Toolkit.Content\ApplicationBar.Select.png" />
+    <Content Include="add.png" />
   </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="Resources\AppResources.resx">
@@ -183,6 +182,22 @@
       <HintPath>..\..\packages\Newtonsoft.Json.6.0.8\lib\portable-net40+sl5+wp80+win8+wpa81\Newtonsoft.Json.dll</HintPath>
       <Private>True</Private>
     </Reference>
+    <Reference Include="PCLStorage, Version=1.0.2.0, Culture=neutral, PublicKeyToken=286fe515a2c35b64, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\PCLStorage.1.0.2\lib\wp8\PCLStorage.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="PCLStorage.Abstractions, Version=1.0.2.0, Culture=neutral, PublicKeyToken=286fe515a2c35b64, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\PCLStorage.1.0.2\lib\wp8\PCLStorage.Abstractions.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Refractored.Xam.TTS, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Xam.Plugins.TextToSpeech.1.0.1\lib\wp8\Refractored.Xam.TTS.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Refractored.Xam.TTS.Abstractions, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\..\packages\Xam.Plugins.TextToSpeech.1.0.1\lib\wp8\Refractored.Xam.TTS.Abstractions.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
     <Reference Include="SQLitePCL, Version=3.8.7.2, Culture=neutral, PublicKeyToken=bddade01e9c850c5, processorArchitecture=MSIL">
       <HintPath>..\..\packages\SQLitePCL.3.8.7.2\lib\wp8\SQLitePCL.dll</HintPath>
       <Private>True</Private>
@@ -221,11 +236,18 @@
     </Reference>
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="..\..\TripExpenses.UI\TripExpenses.UI.csproj">
+      <Project>{e1df5355-b3f1-4991-a022-897c33dd29db}</Project>
+      <Name>TripExpenses.UI</Name>
+    </ProjectReference>
+  </ItemGroup>
+<ItemGroup>
     <SDKReference Include="SQLite.WP80, Version=3.8.7">
-      <Name>SQLite for Windows Phone %28SQLite.WP80, Version=3.8.7%29</Name>
+      <Name>SQLite for Windows Phone</Name>
     </SDKReference>
   </ItemGroup>
   <Import Project="..\TripExpenses\TripExpenses.projitems" Label="Shared" Condition="Exists('..\TripExpenses\TripExpenses.projitems')" />
+  <Import Project="..\TripExpenses\TripExpenses.Shared.projitems" Label="Shared" Condition="Exists('..\TripExpenses\TripExpenses.Shared.projitems')" />
   <Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\Microsoft.$(TargetFrameworkIdentifier).$(TargetFrameworkVersion).Overrides.targets" />
   <Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\$(TargetFrameworkVersion)\Microsoft.$(TargetFrameworkIdentifier).CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it.

binární
Demos/TripExpenses/TripExpenses/TripExpenses.WinPhone/add.png


+ 2 - 0
Demos/TripExpenses/TripExpenses/TripExpenses.WinPhone/packages.config

@@ -4,9 +4,11 @@
   <package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="wp80" />
   <package id="Microsoft.Net.Http" version="2.2.29" targetFramework="wp80" />
   <package id="Newtonsoft.Json" version="6.0.8" targetFramework="wp80" />
+  <package id="PCLStorage" version="1.0.2" targetFramework="wp80" />
   <package id="SQLitePCL" version="3.8.7.2" targetFramework="wp80" />
   <package id="WindowsAzure.MobileServices" version="1.3.2" targetFramework="wp80" />
   <package id="WindowsAzure.MobileServices.SQLiteStore" version="1.0.4" targetFramework="wp80" />
   <package id="WPtoolkit" version="4.2013.08.16" targetFramework="wp80" />
+  <package id="Xam.Plugins.TextToSpeech" version="1.0.1" targetFramework="wp80" />
   <package id="Xamarin.Forms" version="1.4.2.6359" targetFramework="wp80" />
 </packages>

binární
Demos/TripExpenses/TripExpenses/TripExpenses.iOS/Resources/add.png


binární
Demos/TripExpenses/TripExpenses/TripExpenses.iOS/Resources/add@2x.png


binární
Demos/TripExpenses/TripExpenses/TripExpenses.iOS/Resources/add@3x.png


+ 45 - 43
Demos/TripExpenses/TripExpenses/TripExpenses.iOS/TripExpenses.iOS.csproj

@@ -3,8 +3,6 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
-    <ProductVersion>8.0.30703</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{D6028D44-6FAD-4A97-A934-90435BAB207A}</ProjectGuid>
     <ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
     <OutputType>Exe</OutputType>
@@ -26,18 +24,13 @@
     <ConsolePause>false</ConsolePause>
     <MtouchLink>None</MtouchLink>
     <MtouchDebug>True</MtouchDebug>
-    <MtouchSdkVersion>7.1</MtouchSdkVersion>
-    <MtouchProfiling>False</MtouchProfiling>
-    <MtouchExtraArgs />
-    <MtouchFastDev>False</MtouchFastDev>
-    <MtouchEnableGenericValueTypeSharing>True</MtouchEnableGenericValueTypeSharing>
-    <MtouchArch>Default, ARMv7</MtouchArch>
-    <MtouchUseLlvm>False</MtouchUseLlvm>
-    <MtouchUseThumb>False</MtouchUseThumb>
-    <MtouchUseSGen>False</MtouchUseSGen>
-    <MtouchUseRefCounting>False</MtouchUseRefCounting>
+    <MtouchSdkVersion>8.3</MtouchSdkVersion>
+    <MtouchArch>i386</MtouchArch>
     <MtouchOptimizePNGs>True</MtouchOptimizePNGs>
-    <MtouchI18n />
+    <MtouchI18n>
+    </MtouchI18n>
+    <CodesignKey>iPhone Developer</CodesignKey>
+    <MtouchUseRefCounting>true</MtouchUseRefCounting>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
     <DebugType>none</DebugType>
@@ -97,62 +90,65 @@
     <None Include="packages.config" />
   </ItemGroup>
   <ItemGroup>
-    <Reference Include="Microsoft.WindowsAzure.Mobile, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+    <Reference Include="System" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Core" />
+    <Reference Include="Xamarin.iOS" />
+    <Reference Include="Microsoft.WindowsAzure.Mobile, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
       <HintPath>..\..\packages\WindowsAzure.MobileServices.1.3.2\lib\Xamarin.iOS10\Microsoft.WindowsAzure.Mobile.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="Microsoft.WindowsAzure.Mobile.Ext, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+    <Reference Include="Microsoft.WindowsAzure.Mobile.Ext, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
       <HintPath>..\..\packages\WindowsAzure.MobileServices.1.3.2\lib\Xamarin.iOS10\Microsoft.WindowsAzure.Mobile.Ext.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="Microsoft.WindowsAzure.Mobile.SQLiteStore, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+    <Reference Include="Microsoft.WindowsAzure.Mobile.SQLiteStore, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
       <HintPath>..\..\packages\WindowsAzure.MobileServices.SQLiteStore.1.0.4\lib\portable-win+net45+wp8+wpa81+monotouch+monoandroid\Microsoft.WindowsAzure.Mobile.SQLiteStore.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+    <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
       <HintPath>..\..\packages\Newtonsoft.Json.6.0.8\lib\portable-net40+sl5+wp80+win8+wpa81\Newtonsoft.Json.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="SQLitePCL, Version=3.8.7.2, Culture=neutral, PublicKeyToken=bddade01e9c850c5, processorArchitecture=MSIL">
+    <Reference Include="SQLitePCL, Version=3.8.7.2, Culture=neutral, PublicKeyToken=bddade01e9c850c5">
       <HintPath>..\..\packages\SQLitePCL.3.8.7.2\lib\Xamarin.iOS10\SQLitePCL.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="SQLitePCL.Ext, Version=3.8.7.2, Culture=neutral, PublicKeyToken=bddade01e9c850c5, processorArchitecture=MSIL">
+    <Reference Include="SQLitePCL.Ext, Version=3.8.7.2, Culture=neutral, PublicKeyToken=bddade01e9c850c5">
       <HintPath>..\..\packages\SQLitePCL.3.8.7.2\lib\Xamarin.iOS10\SQLitePCL.Ext.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Net.Http" />
-    <Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+    <Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
       <HintPath>..\..\packages\Microsoft.Net.Http.2.2.29\lib\Xamarin.iOS10\System.Net.Http.Extensions.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+    <Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
       <HintPath>..\..\packages\Microsoft.Net.Http.2.2.29\lib\Xamarin.iOS10\System.Net.Http.Primitives.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="System.Xml" />
-    <Reference Include="System.Core" />
-    <Reference Include="Xamarin.Forms.Core, Version=1.4.0.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="Xamarin.Forms.Core, Version=1.4.0.0, Culture=neutral, PublicKeyToken=null">
       <HintPath>..\..\packages\Xamarin.Forms.1.4.2.6359\lib\Xamarin.iOS10\Xamarin.Forms.Core.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="Xamarin.Forms.Platform, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="Xamarin.Forms.Platform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
       <HintPath>..\..\packages\Xamarin.Forms.1.4.2.6359\lib\Xamarin.iOS10\Xamarin.Forms.Platform.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="Xamarin.Forms.Platform.iOS, Version=1.4.0.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="Xamarin.Forms.Platform.iOS, Version=1.4.0.0, Culture=neutral, PublicKeyToken=null">
       <HintPath>..\..\packages\Xamarin.Forms.1.4.2.6359\lib\Xamarin.iOS10\Xamarin.Forms.Platform.iOS.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="Xamarin.Forms.Xaml, Version=1.4.0.0, Culture=neutral, processorArchitecture=MSIL">
+    <Reference Include="Xamarin.Forms.Xaml, Version=1.4.0.0, Culture=neutral, PublicKeyToken=null">
       <HintPath>..\..\packages\Xamarin.Forms.1.4.2.6359\lib\Xamarin.iOS10\Xamarin.Forms.Xaml.dll</HintPath>
-      <Private>True</Private>
     </Reference>
-    <Reference Include="Xamarin.iOS" />
+    <Reference Include="PCLStorage">
+      <HintPath>..\..\packages\PCLStorage.1.0.2\lib\portable-Xamarin.iOS+Xamarin.Mac\PCLStorage.dll</HintPath>
+    </Reference>
+    <Reference Include="PCLStorage.Abstractions">
+      <HintPath>..\..\packages\PCLStorage.1.0.2\lib\portable-Xamarin.iOS+Xamarin.Mac\PCLStorage.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Refractored.Xam.TTS.Abstractions">
+      <HintPath>..\..\packages\Xam.Plugins.TextToSpeech.1.0.1\lib\Xamarin.iOS10\Refractored.Xam.TTS.Abstractions.dll</HintPath>
+    </Reference>
+    <Reference Include="Refractored.Xam.TTS">
+      <HintPath>..\..\packages\Xam.Plugins.TextToSpeech.1.0.1\lib\Xamarin.iOS10\Refractored.Xam.TTS.dll</HintPath>
+    </Reference>
   </ItemGroup>
   <ItemGroup>
     <BundleResource Include="Resources\Default-568h%402x.png" />
+    <BundleResource Include="Resources\add.png" />
+    <BundleResource Include="Resources\add%402x.png" />
+    <BundleResource Include="Resources\add%403x.png" />
   </ItemGroup>
   <ItemGroup>
     <BundleResource Include="Resources\refresh%402x.png" />
@@ -160,7 +156,7 @@
   <ItemGroup>
     <BundleResource Include="Resources\refresh.png" />
   </ItemGroup>
-  <Import Project="..\TripExpenses\TripExpenses.projitems" Label="Shared" Condition="Exists('..\TripExpenses\TripExpenses.projitems')" />
+  <Import Project="..\TripExpenses\TripExpenses.Shared.projitems" Label="Shared" Condition="Exists('..\TripExpenses\TripExpenses.Shared.projitems')" />
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
   <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
     <PropertyGroup>
@@ -173,4 +169,10 @@
   <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
   <Import Project="..\..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
   <Import Project="..\..\packages\Xamarin.Forms.1.4.2.6359\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.targets" Condition="Exists('..\..\packages\Xamarin.Forms.1.4.2.6359\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.targets')" />
+  <ItemGroup>
+    <ProjectReference Include="..\..\TripExpenses.UI\TripExpenses.UI.csproj">
+      <Project>{E1DF5355-B3F1-4991-A022-897C33DD29DB}</Project>
+      <Name>TripExpenses.UI</Name>
+    </ProjectReference>
+  </ItemGroup>
 </Project>

+ 2 - 0
Demos/TripExpenses/TripExpenses/TripExpenses.iOS/packages.config

@@ -4,8 +4,10 @@
   <package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="xamarinios10" />
   <package id="Microsoft.Net.Http" version="2.2.29" targetFramework="xamarinios10" />
   <package id="Newtonsoft.Json" version="6.0.8" targetFramework="xamarinios10" />
+  <package id="PCLStorage" version="1.0.2" targetFramework="xamarinios10" />
   <package id="SQLitePCL" version="3.8.7.2" targetFramework="xamarinios10" />
   <package id="WindowsAzure.MobileServices" version="1.3.2" targetFramework="xamarinios10" />
   <package id="WindowsAzure.MobileServices.SQLiteStore" version="1.0.4" targetFramework="xamarinios10" />
+  <package id="Xam.Plugins.TextToSpeech" version="1.0.1" targetFramework="xamarinios10" />
   <package id="Xamarin.Forms" version="1.4.2.6359" targetFramework="xamarinios10" />
 </packages>

+ 18 - 0
Demos/TripExpenses/TripExpenses/TripExpenses/Interfaces/IDataStore.cs

@@ -0,0 +1,18 @@
+using System;
+using System.Threading.Tasks;
+using TripExpenses.Models;
+using System.Collections.Generic;
+
+namespace TripExpenses
+{
+	public interface IDataStore
+	{
+		Task Init();
+		Task<TripExpense> InsertExpenseAsync(TripExpense expense);
+		Task<TripExpense> UpdateExpenseAsync(TripExpense expense);
+		Task<IEnumerable<TripExpense>> GetExpensesAsync();
+		Task SyncExpensesAsync();
+		Task DeleteExpenseAsync(TripExpense expense);
+	}
+}
+

+ 11 - 1
Demos/TripExpenses/TripExpenses/TripExpenses/Models/TripExpense.cs

@@ -7,6 +7,10 @@ namespace TripExpenses.Models
 {
   public class TripExpense
   {
+		public TripExpense()
+		{
+		}
+
     [JsonProperty(PropertyName = "id")]
     public string Id { get; set; }
 
@@ -19,6 +23,12 @@ namespace TripExpenses.Models
     [Microsoft.WindowsAzure.MobileServices.Version]
     public string Version { get; set; }  
 
-
+		public void SyncProperties(TripExpense expense)
+		{
+			this.Billable = expense.Billable;
+			this.Category = expense.Category;
+			this.Name = expense.Name;
+			this.Price = expense.Price;
+		}
   }
 }

+ 27 - 13
Demos/TripExpenses/TripExpenses/TripExpenses/Services/DataStore.cs → Demos/TripExpenses/TripExpenses/TripExpenses/Services/AzureDataStore.cs

@@ -8,10 +8,15 @@ using Microsoft.WindowsAzure.MobileServices.SQLiteStore;
 using Microsoft.WindowsAzure.MobileServices.Sync;
 using System.Diagnostics;
 using System;
+using Xamarin.Forms;
+using TripExpenses.Services;
 
+//Comment back in to use azure
+
+//[assembly: Dependency(typeof(AzureDataStore))]
 namespace TripExpenses.Services
 {
-  public class DataStore
+  public class AzureDataStore : IDataStore
   {
     public List<TripExpense> Expenses { get; set; }
     public MobileServiceClient MobileService { get; set; }
@@ -19,7 +24,7 @@ namespace TripExpenses.Services
     private IMobileServiceSyncTable<TripExpense> expenseTable;
     private bool initialized = false;
 
-    public DataStore()
+    public AzureDataStore()
     {
 
       Expenses = new List<TripExpense>();
@@ -34,8 +39,8 @@ namespace TripExpenses.Services
 
       //comment back in to enable Azure Mobile Services.
       MobileService = new MobileServiceClient("https://" 
-		+ "PUT-SITE-HERE" + ".azure-mobile.net/",
-		"PUT-API-KEY-HERE");
+		+ "SITE-HERE" + ".azure-mobile.net/",
+				"API-KEY-HERE");
 
       
     }
@@ -52,30 +57,39 @@ namespace TripExpenses.Services
     }
 
 
-    public async Task InsertExpenseAsync(TripExpense expense)
+		public async Task<TripExpense> InsertExpenseAsync(TripExpense expense)
     {
       if (!initialized)
         await Init();
-      //expense.Id = (Expenses.Count + 1).ToString();
-      //Expenses.Add(expense);
+
       
       await expenseTable.InsertAsync(expense);
+			return expense;
     }
 
-    public async Task UpdateExpenseAsync(TripExpense expense)
+		public async Task<TripExpense> UpdateExpenseAsync(TripExpense expense)
     {
       if (!initialized)
         await Init();
       
       await expenseTable.UpdateAsync(expense);
+			return expense;
     }
 
+		public async Task DeleteExpenseAsync(TripExpense expense)
+		{
+			if (!initialized)
+				await Init();
+
+
+			await expenseTable.DeleteAsync(expense);
+		}
+
     public async Task<IEnumerable<TripExpense>> GetExpensesAsync()
     {
       if (!initialized)
         await Init();
 
-      //return Expenses;
       await SyncExpensesAsync();
       return await expenseTable.ToEnumerableAsync();
     }
@@ -85,7 +99,7 @@ namespace TripExpenses.Services
       try
       {
         await MobileService.SyncContext.PushAsync();
-		await expenseTable.PullAsync("allItems", expenseTable.CreateQuery());
+				await expenseTable.PullAsync("allItems", expenseTable.CreateQuery());
       }
       catch(Exception ex)
       {
@@ -95,15 +109,15 @@ namespace TripExpenses.Services
 
 
 
-    static readonly DataStore instance = new DataStore();
+    static readonly AzureDataStore instance = new AzureDataStore();
     /// <summary>
     /// Gets the instance of the Azure Web Service
     /// </summary>
-    public static DataStore Instance
+    public static AzureDataStore Instance
     {
       get
       {
-        return instance;
+		return instance;
       }
     }
 

+ 132 - 0
Demos/TripExpenses/TripExpenses/TripExpenses/Services/XMLDataStore.cs

@@ -0,0 +1,132 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using System.Linq;
+using PCLStorage;
+using TripExpenses.Models;
+using Xamarin.Forms;
+using TripExpenses;
+
+//Comment out to use azure
+[assembly:Dependency(typeof(XmlDataStore))]
+namespace TripExpenses
+{
+	public class XmlDataStore : IDataStore
+	{
+
+		public XmlDataStore()
+		{
+		}
+
+
+		public static Task<T> DeserializeObjectAsync<T>(string value)
+		{
+			return Task.Factory.StartNew(() => JsonConvert.DeserializeObject<T>(value));
+		}
+
+		public static T DeserializeObject<T>(string value)
+		{
+			return JsonConvert.DeserializeObject<T>(value);
+		}
+
+		List<TripExpense> Expenses = new List<TripExpense>();
+
+		public Task<TripExpense> GetExpenseAsync(string id)
+		{
+			return Task.Run(()=>Expenses.FirstOrDefault(s => s.Id == id));
+		}
+
+		public async Task<IEnumerable<TripExpense>> GetExpensesAsync()
+		{
+			var rootFolder = FileSystem.Current.LocalStorage;
+
+			var folder = await rootFolder.CreateFolderAsync(Folder,
+				CreationCollisionOption.OpenIfExists);
+
+			var file = await folder.CreateFileAsync(File,
+				CreationCollisionOption.OpenIfExists);
+
+			var json = await file.ReadAllTextAsync();
+
+			if(!string.IsNullOrWhiteSpace(json))
+				Expenses = DeserializeObject<List<TripExpense>>(json);
+
+			if(Expenses.Count == 0)
+			{
+				var expense =  new TripExpense
+				{
+					Billable = true,
+					Category = "Transportation",
+					Name = "DevWeek 2015 Flight",
+					Price = "1000.00"
+				};
+				await SaveExpenseAsync(expense);
+			}
+
+			return Expenses;
+		}
+
+		public Task SyncExpensesAsync()
+		{
+			return Task.Run(() => { });
+		}
+
+		public async Task<TripExpense> InsertExpenseAsync(TripExpense expense)
+		{
+			return await SaveExpenseAsync (expense);
+		}
+
+		public async Task<TripExpense> UpdateExpenseAsync(TripExpense expense)
+		{
+			return await SaveExpenseAsync (expense);
+		}
+
+		public async Task<TripExpense> SaveExpenseAsync(TripExpense expense)
+		{
+			if(string.IsNullOrWhiteSpace(expense.Id))
+			{
+				expense.Id = DateTime.Now.ToString();
+				Expenses.Add(expense);
+			}
+			else
+			{
+				var found = Expenses.FirstOrDefault(e => e.Id == expense.Id);
+				if(found != null)
+					found.SyncProperties(expense);
+			}
+			await Save();
+			return expense;
+		}
+
+		public async Task DeleteExpenseAsync(TripExpense expense)
+		{
+			var id = expense.Id;
+			Expenses.Remove(expense);
+			await Save();
+		}
+
+		private string Folder = "Expenses";
+		private string File = "expenses.json";
+
+		private async Task Save()
+		{
+			var rootFolder = FileSystem.Current.LocalStorage;
+
+			var folder = await rootFolder.CreateFolderAsync(Folder,
+				CreationCollisionOption.OpenIfExists);
+
+			var file = await folder.CreateFileAsync(File,
+				CreationCollisionOption.ReplaceExisting);
+
+			await file.WriteAllTextAsync(JsonConvert.SerializeObject(Expenses));
+		}
+			
+
+		public Task Init()
+		{
+			return null;
+		}
+	}
+}
+

+ 6 - 3
Demos/TripExpenses/TripExpenses/TripExpenses/TripExpenses.projitems → Demos/TripExpenses/TripExpenses/TripExpenses/TripExpenses.Shared.projitems

@@ -11,10 +11,12 @@
   <ItemGroup>
     <Compile Include="$(MSBuildThisFileDirectory)App.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Models\TripExpense.cs" />
-    <Compile Include="$(MSBuildThisFileDirectory)Services\DataStore.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)ViewModels\BaseViewModel.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)ViewModels\DetailViewModel.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)ViewModels\ExpensesViewModel.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Interfaces\IDataStore.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Services\AzureDataStore.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Services\XMLDataStore.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Views\DetailsPage.xaml.cs">
       <DependentUpon>DetailsPage.xaml</DependentUpon>
       <SubType>Code</SubType>
@@ -24,13 +26,14 @@
       <SubType>Code</SubType>
     </Compile>
   </ItemGroup>
+  <ItemGroup>
+    <Folder Include="$(MSBuildThisFileDirectory)Interfaces\" />
+  </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="$(MSBuildThisFileDirectory)Views\DetailsPage.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </EmbeddedResource>
-  </ItemGroup>
-  <ItemGroup>
     <EmbeddedResource Include="$(MSBuildThisFileDirectory)Views\ExpenseListPage.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>

+ 2 - 2
Demos/TripExpenses/TripExpenses/TripExpenses/TripExpenses.shproj → Demos/TripExpenses/TripExpenses/TripExpenses/TripExpenses.Shared.shproj

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup Label="Globals">
     <ProjectGuid>908b9ab7-c998-4b59-b85e-ec37794fb92b</ProjectGuid>
   </PropertyGroup>
@@ -7,6 +7,6 @@
   <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
   <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
   <PropertyGroup />
-  <Import Project="TripExpenses.projitems" Label="Shared" />
+  <Import Project="TripExpenses.Shared.projitems" Label="Shared" />
   <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
 </Project>

+ 5 - 3
Demos/TripExpenses/TripExpenses/TripExpenses/ViewModels/DetailViewModel.cs

@@ -22,8 +22,10 @@ namespace TripExpenses.ViewModels
     private bool isNew;
 
     INavigation navigation;
+		IDataStore dataStore;
     public DetailViewModel(TripExpense expense, INavigation navigation)
     {
+			dataStore = DependencyService.Get<IDataStore> ();
       this.navigation = navigation;
       if(expense == null)
       {
@@ -66,12 +68,12 @@ namespace TripExpenses.ViewModels
 
 
       if (isNew)
-        await DataStore.Instance.InsertExpenseAsync(expense);
+				await dataStore.InsertExpenseAsync(expense);
       else
-        await DataStore.Instance.UpdateExpenseAsync(expense);
+				await dataStore.UpdateExpenseAsync(expense);
 
 
-      await DataStore.Instance.SyncExpensesAsync();
+			await dataStore.SyncExpensesAsync();
 
       //Send a message to insert/update the expense to all subscribers
       if(isNew)

+ 43 - 3
Demos/TripExpenses/TripExpenses/TripExpenses/ViewModels/ExpensesViewModel.cs

@@ -16,11 +16,12 @@ namespace TripExpenses.ViewModels
     public bool Initialized { get; set; }
 
     public ObservableCollection<TripExpense> Expenses { get; set; }
+		IDataStore dataStore;
 
     public ExpensesViewModel()
-    { 
+		{ 
+			dataStore = DependencyService.Get<IDataStore> ();
       Expenses = new ObservableCollection<TripExpense>();
-
       //Subscibe to insert expenses
       MessagingCenter.Subscribe<TripExpense>(this, "NewExpense", (expense) =>
       {
@@ -55,7 +56,7 @@ namespace TripExpenses.ViewModels
 
       Expenses.Clear();
 
-      var expenses = await DataStore.Instance.GetExpensesAsync();
+			var expenses = await dataStore.GetExpensesAsync();
       foreach (var expense in expenses)
        Expenses.Add(expense);
 
@@ -80,5 +81,44 @@ namespace TripExpenses.ViewModels
       Expenses[index] = expense;
       IsBusy = false;
     }
+
+		private Command<TripExpense> deleteExpense;
+		public ICommand DeleteExpense
+		{
+			get
+			{
+				return deleteExpense ??
+					(deleteExpense = new Command<TripExpense>((expense)=>ExecuteDeleteExpense(expense)));
+			}
+		}
+
+		private async Task ExecuteDeleteExpense(TripExpense expense)
+		{
+			IsBusy = true;
+			await dataStore.DeleteExpenseAsync(expense);
+			await dataStore.SyncExpensesAsync ();
+			Expenses.Remove (expense);
+			IsBusy = false;
+		}
+
+
+		public void SpeakTotal()
+		{
+			var total = 0.0f;
+			var temp = 0.0f;
+			foreach (var expense in Expenses) {
+				
+				if (float.TryParse (expense.Price, out temp))
+					total += temp;
+			}
+
+			var message = "You have a total of " + 
+				Expenses.Count + 
+				" expenses that need to be filed totaling " +
+				total.ToString("C");
+	
+
+
+		}
   }
 }

+ 14 - 5
Demos/TripExpenses/TripExpenses/TripExpenses/Views/DetailsPage.xaml

@@ -1,13 +1,21 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
-			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
 			 x:Class="TripExpenses.Views.DetailsPage"
+		     xmlns:local="clr-namespace:TripExpenses.UI;assembly=TripExpenses.UI"
              Title="Details">
+     <ContentPage.Resources>
+	     <ResourceDictionary>
+	   		<local:MultiTriggerConverter x:Key="dataHasBeenEntered" />
+		</ResourceDictionary>
+	</ContentPage.Resources>
 	<StackLayout Padding="20" Spacing="20">
-        <Entry Placeholder="Expense Name"
+        <Entry x:Name="ExpenseName"
+        	   Placeholder="Expense Name"
                Text="{Binding Name, Mode=TwoWay}"/>
         
-        <Entry Placeholder="0.00"
+        <Entry x:Name="ExpenseTotal"
+               Placeholder="0.00"
                Text="{Binding Price, Mode=TwoWay}"
                Keyboard="Numeric"/>
         
@@ -15,7 +23,6 @@
             <Label Text ="Billable" VerticalOptions="Center"/>
             <Switch IsToggled="{Binding Billable}"/>
         </StackLayout>
-        
         <Picker x:Name="PickerCategory"
                 Title="Category"
                 SelectedIndex="{Binding Category}"/>
@@ -24,7 +31,9 @@
                 BackgroundColor="#77D065"
                 TextColor="#FFFFFF"
                 HorizontalOptions="FillAndExpand"
-                Command="{Binding SaveCommand}"/>
+                Command="{Binding SaveCommand}">
+             
+        </Button>
         
          <ActivityIndicator IsVisible="{Binding IsBusy}"
                             IsRunning="{Binding IsBusy}"/>

+ 3 - 1
Demos/TripExpenses/TripExpenses/TripExpenses/Views/DetailsPage.xaml.cs

@@ -6,11 +6,13 @@ using System.Threading.Tasks;
 using TripExpenses.Models;
 using TripExpenses.ViewModels;
 using Xamarin.Forms;
+using TripExpenses.UI;
 
 namespace TripExpenses.Views
 {
 	public partial class DetailsPage
 	{
+		
 		public DetailViewModel ViewModel
 		{
 			get { return BindingContext as DetailViewModel; }
@@ -20,7 +22,7 @@ namespace TripExpenses.Views
 		public DetailsPage(TripExpense expense)
 		{
 			InitializeComponent();
-
+			Type type = typeof(MultiTriggerConverter);
 			foreach (var item in DetailViewModel.Categories)
 				PickerCategory.Items.Add(item);
 

+ 25 - 21
Demos/TripExpenses/TripExpenses/TripExpenses/Views/ExpenseListPage.xaml

@@ -1,26 +1,30 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
-					   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
-					   x:Class="TripExpenses.Views.ExpenseListPage"
-             Title="Expenses">
+			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+			 x:Class="TripExpenses.Views.ExpenseListPage"
+			 Title="Expenses"
+       IsBusy="{Binding IsBusy}">
+   <ContentPage.ToolbarItems>
+   	<ToolbarItem x:Name="AddItem" Text="add" Icon="add.png"/>
+   </ContentPage.ToolbarItems>
     <ContentPage.Content>
-        <StackLayout Spacing="10" Padding="10">
-            <ActivityIndicator IsVisible="{Binding IsBusy}"
-                    IsRunning="{Binding IsBusy}"/>
-
-            <ListView x:Name="ExpenseList" ItemsSource="{Binding Expenses}">
-                <ListView.ItemTemplate>
-                    <DataTemplate>
-                        <TextCell Text="{Binding Name}"
-                        Detail="{Binding Price}"/>
-                    </DataTemplate>
-                </ListView.ItemTemplate>
-            </ListView>
-
-            <Button x:Name="ButtonNewExpense"
-                    Text="Add Expense"
-                      BackgroundColor="#77D065"
-                TextColor="#FFFFFF"/>
-        </StackLayout>
+        <ListView x:Name="ExpenseList" 
+        		 ItemsSource="{Binding Expenses}"
+        		 IsPullToRefreshEnabled="true"
+        		 RefreshCommand="{Binding LoadExpenses}"
+        		 IsRefreshing="{Binding IsBusy, Mode=OneWay}">
+            <ListView.ItemTemplate>
+                <DataTemplate>
+                    <TextCell Text="{Binding Name}"
+                    Detail="{Binding Price}">
+                     	<TextCell.ContextActions>
+                     		<MenuItem Clicked="OnDelete"
+           						Text="Delete" IsDestructive="True" 
+           						CommandParameter="{Binding .}"/>
+                     	</TextCell.ContextActions>
+                    </TextCell>
+                </DataTemplate>
+            </ListView.ItemTemplate>
+        </ListView>
     </ContentPage.Content>
 </ContentPage>

+ 12 - 12
Demos/TripExpenses/TripExpenses/TripExpenses/Views/ExpenseListPage.xaml.cs

@@ -19,12 +19,11 @@ namespace TripExpenses.Views
 
 			this.BindingContext = viewModel = new ExpensesViewModel();
 
-			ToolbarItems.Add(new ToolbarItem
-			  {
-				  Name = "refresh",
-				  Icon = "refresh.png",
-				  Command = viewModel.LoadExpenses
-			  });
+			AddItem.Command = new Command (() => {
+				var detailPage = new DetailsPage (null);
+				Navigation.PushAsync (detailPage);
+			});
+
 
 			ExpenseList.ItemTapped += (sender, args) =>
 			{
@@ -36,12 +35,13 @@ namespace TripExpenses.Views
 
 				ExpenseList.SelectedItem = null;
 			};
+				
 
-			ButtonNewExpense.Clicked += async (sender, args) =>
-			{
-				var detailPage = new DetailsPage(null);
-				await Navigation.PushAsync(detailPage);
-			};
+		}
+
+		public void OnDelete (object sender, EventArgs e) {
+			var mi = ((MenuItem)sender);
+			viewModel.DeleteExpense.Execute (mi.CommandParameter);
 		}
 
 
@@ -53,4 +53,4 @@ namespace TripExpenses.Views
 				viewModel.LoadExpenses.Execute(null);
 		}
 	}
-}
+}