@ -0,0 +1,256 @@ | |||
# Created by https://www.gitignore.io/api/visualstudio | |||
### VisualStudio ### | |||
## Ignore Visual Studio temporary files, build results, and | |||
## files generated by popular Visual Studio add-ons. | |||
# User-specific files | |||
*.suo | |||
*.user | |||
*.userosscache | |||
*.sln.docstates | |||
# User-specific files (MonoDevelop/Xamarin Studio) | |||
*.userprefs | |||
# Build results | |||
[Dd]ebug/ | |||
[Dd]ebugPublic/ | |||
[Rr]elease/ | |||
[Rr]eleases/ | |||
x64/ | |||
x86/ | |||
bld/ | |||
[Bb]in/ | |||
[Oo]bj/ | |||
[Ll]og/ | |||
# Visual Studio 2015 cache/options directory | |||
.vs/ | |||
# Uncomment if you have tasks that create the project's static files in wwwroot | |||
wwwroot/ | |||
# MSTest test Results | |||
[Tt]est[Rr]esult*/ | |||
[Bb]uild[Ll]og.* | |||
# NUNIT | |||
*.VisualState.xml | |||
TestResult.xml | |||
# Build Results of an ATL Project | |||
[Dd]ebugPS/ | |||
[Rr]eleasePS/ | |||
dlldata.c | |||
# DNX | |||
project.lock.json | |||
project.fragment.lock.json | |||
artifacts/ | |||
*_i.c | |||
*_p.c | |||
*_i.h | |||
*.ilk | |||
*.meta | |||
*.obj | |||
*.pch | |||
*.pdb | |||
*.pgc | |||
*.pgd | |||
*.rsp | |||
*.sbr | |||
*.tlb | |||
*.tli | |||
*.tlh | |||
*.tmp | |||
*.tmp_proj | |||
*.log | |||
*.vspscc | |||
*.vssscc | |||
.builds | |||
*.pidb | |||
*.svclog | |||
*.scc | |||
# Chutzpah Test files | |||
_Chutzpah* | |||
# Visual C++ cache files | |||
ipch/ | |||
*.aps | |||
*.ncb | |||
*.opendb | |||
*.opensdf | |||
*.sdf | |||
*.cachefile | |||
*.VC.db | |||
*.VC.VC.opendb | |||
# Visual Studio profiler | |||
*.psess | |||
*.vsp | |||
*.vspx | |||
*.sap | |||
# TFS 2012 Local Workspace | |||
$tf/ | |||
# Guidance Automation Toolkit | |||
*.gpState | |||
# ReSharper is a .NET coding add-in | |||
_ReSharper*/ | |||
*.[Rr]e[Ss]harper | |||
*.DotSettings.user | |||
# JustCode is a .NET coding add-in | |||
.JustCode | |||
# TeamCity is a build add-in | |||
_TeamCity* | |||
# DotCover is a Code Coverage Tool | |||
*.dotCover | |||
# NCrunch | |||
_NCrunch_* | |||
.*crunch*.local.xml | |||
nCrunchTemp_* | |||
# MightyMoose | |||
*.mm.* | |||
AutoTest.Net/ | |||
# Web workbench (sass) | |||
.sass-cache/ | |||
# 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 | |||
*.[Pp]ublish.xml | |||
*.azurePubxml | |||
# TODO: Comment the next line if you want to checkin your web deploy settings | |||
# but database connection strings (with potential passwords) will be unencrypted | |||
*.pubxml | |||
*.publishproj | |||
# Microsoft Azure Web App publish settings. Comment the next line if you want to | |||
# checkin your Azure Web App publish settings, but sensitive information contained | |||
# in these scripts will be unencrypted | |||
PublishScripts/ | |||
# NuGet Packages | |||
*.nupkg | |||
# The packages folder can be ignored because of Package Restore | |||
**/packages/* | |||
# except build/, which is used as an MSBuild target. | |||
!**/packages/build/ | |||
# Uncomment if necessary however generally it will be regenerated when needed | |||
#!**/packages/repositories.config | |||
# NuGet v3's project.json files produces more ignoreable files | |||
*.nuget.props | |||
*.nuget.targets | |||
# Microsoft Azure Build Output | |||
csx/ | |||
*.build.csdef | |||
# Microsoft Azure Emulator | |||
ecf/ | |||
rcf/ | |||
# Windows Store app package directories and files | |||
AppPackages/ | |||
BundleArtifacts/ | |||
Package.StoreAssociation.xml | |||
_pkginfo.txt | |||
# Visual Studio cache files | |||
# files ending in .cache can be ignored | |||
*.[Cc]ache | |||
# but keep track of directories ending in .cache | |||
!*.[Cc]ache/ | |||
# Others | |||
ClientBin/ | |||
~$* | |||
*~ | |||
*.dbmdl | |||
*.dbproj.schemaview | |||
*.pfx | |||
*.publishsettings | |||
node_modules/ | |||
orleans.codegen.cs | |||
# Since there are multiple workflows, uncomment next line to ignore bower_components | |||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) | |||
#bower_components/ | |||
# 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 | |||
*.mdf | |||
*.ldf | |||
# Business Intelligence projects | |||
*.rdl.data | |||
*.bim.layout | |||
*.bim_*.settings | |||
# Microsoft Fakes | |||
FakesAssemblies/ | |||
# GhostDoc plugin setting file | |||
*.GhostDoc.xml | |||
# Node.js Tools for Visual Studio | |||
.ntvs_analysis.dat | |||
# Visual Studio 6 build log | |||
*.plg | |||
# Visual Studio 6 workspace options file | |||
*.opt | |||
# Visual Studio LightSwitch build output | |||
**/*.HTMLClient/GeneratedArtifacts | |||
**/*.DesktopClient/GeneratedArtifacts | |||
**/*.DesktopClient/ModelManifest.xml | |||
**/*.Server/GeneratedArtifacts | |||
**/*.Server/ModelManifest.xml | |||
_Pvt_Extensions | |||
# Paket dependency manager | |||
.paket/paket.exe | |||
paket-files/ | |||
# FAKE - F# Make | |||
.fake/ |
@ -0,0 +1,261 @@ | |||
| |||
Microsoft Visual Studio Solution File, Format Version 12.00 | |||
# Visual Studio 14 | |||
VisualStudioVersion = 14.0.25420.1 | |||
MinimumVisualStudioVersion = 10.0.40219.1 | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Droid", "eShopOnContainers\eShopOnContainers.Droid\eShopOnContainers.Droid.csproj", "{62DBB163-9CA9-4818-B48B-13233DF37C24}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.iOS", "eShopOnContainers\eShopOnContainers.iOS\eShopOnContainers.iOS.csproj", "{6EEB23DC-7063-4444-9AF8-90DF24F549C0}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Core", "eShopOnContainers\eShopOnContainers.Core\eShopOnContainers.Core.csproj", "{65116D1C-145B-4693-ABDA-F0FB6F425191}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "eShopOnContainers.Windows", "eShopOnContainers\eShopOnContainers.Windows\eShopOnContainers.Windows.csproj", "{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}" | |||
EndProject | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU | |||
Ad-Hoc|ARM = Ad-Hoc|ARM | |||
Ad-Hoc|iPhone = Ad-Hoc|iPhone | |||
Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator | |||
Ad-Hoc|x64 = Ad-Hoc|x64 | |||
Ad-Hoc|x86 = Ad-Hoc|x86 | |||
AppStore|Any CPU = AppStore|Any CPU | |||
AppStore|ARM = AppStore|ARM | |||
AppStore|iPhone = AppStore|iPhone | |||
AppStore|iPhoneSimulator = AppStore|iPhoneSimulator | |||
AppStore|x64 = AppStore|x64 | |||
AppStore|x86 = AppStore|x86 | |||
Debug|Any CPU = Debug|Any CPU | |||
Debug|ARM = Debug|ARM | |||
Debug|iPhone = Debug|iPhone | |||
Debug|iPhoneSimulator = Debug|iPhoneSimulator | |||
Debug|x64 = Debug|x64 | |||
Debug|x86 = Debug|x86 | |||
Release|Any CPU = Release|Any CPU | |||
Release|ARM = Release|ARM | |||
Release|iPhone = Release|iPhone | |||
Release|iPhoneSimulator = Release|iPhoneSimulator | |||
Release|x64 = Release|x64 | |||
Release|x86 = Release|x86 | |||
EndGlobalSection | |||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|Any CPU.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|ARM.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|ARM.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhone.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x64.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x64.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x86.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Ad-Hoc|x86.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|Any CPU.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|Any CPU.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|Any CPU.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|ARM.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|ARM.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|ARM.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhone.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhone.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhone.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|iPhoneSimulator.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x64.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x64.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x64.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x86.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x86.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.AppStore|x86.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|Any CPU.Deploy.0 = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|ARM.ActiveCfg = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|ARM.Build.0 = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|ARM.Deploy.0 = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhone.ActiveCfg = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhone.Build.0 = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhone.Deploy.0 = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x64.ActiveCfg = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x64.Build.0 = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x64.Deploy.0 = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x86.ActiveCfg = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x86.Build.0 = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Debug|x86.Deploy.0 = Debug|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|Any CPU.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|Any CPU.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|ARM.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|ARM.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|ARM.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhone.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhone.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhone.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhoneSimulator.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x64.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x64.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x64.Deploy.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x86.ActiveCfg = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x86.Build.0 = Release|Any CPU | |||
{62DBB163-9CA9-4818-B48B-13233DF37C24}.Release|x86.Deploy.0 = Release|Any CPU | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|Any CPU.ActiveCfg = Ad-Hoc|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|ARM.ActiveCfg = Ad-Hoc|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|x64.ActiveCfg = Ad-Hoc|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Ad-Hoc|x86.ActiveCfg = Ad-Hoc|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|Any CPU.ActiveCfg = AppStore|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|ARM.ActiveCfg = AppStore|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|iPhone.ActiveCfg = AppStore|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|iPhone.Build.0 = AppStore|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|x64.ActiveCfg = AppStore|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.AppStore|x86.ActiveCfg = AppStore|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|Any CPU.ActiveCfg = Debug|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|Any CPU.Build.0 = Debug|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|ARM.ActiveCfg = Debug|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|iPhone.ActiveCfg = Debug|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|iPhone.Build.0 = Debug|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|x64.ActiveCfg = Debug|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Debug|x86.ActiveCfg = Debug|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|Any CPU.ActiveCfg = Release|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|ARM.ActiveCfg = Release|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|iPhone.ActiveCfg = Release|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|iPhone.Build.0 = Release|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|x64.ActiveCfg = Release|iPhone | |||
{6EEB23DC-7063-4444-9AF8-90DF24F549C0}.Release|x86.ActiveCfg = Release|iPhone | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|ARM.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|ARM.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|x64.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|x64.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Ad-Hoc|x86.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|Any CPU.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|Any CPU.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|ARM.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|ARM.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|iPhone.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|iPhone.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|x64.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|x64.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|x86.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.AppStore|x86.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|ARM.ActiveCfg = Debug|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|ARM.Build.0 = Debug|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|iPhone.ActiveCfg = Debug|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|iPhone.Build.0 = Debug|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|x64.ActiveCfg = Debug|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|x64.Build.0 = Debug|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|x86.ActiveCfg = Debug|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Debug|x86.Build.0 = Debug|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|Any CPU.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|ARM.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|ARM.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|iPhone.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|iPhone.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|iPhoneSimulator.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|x64.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|x64.Build.0 = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|x86.ActiveCfg = Release|Any CPU | |||
{65116D1C-145B-4693-ABDA-F0FB6F425191}.Release|x86.Build.0 = Release|Any CPU | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|Any CPU.ActiveCfg = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|Any CPU.Build.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|Any CPU.Deploy.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|ARM.ActiveCfg = Release|ARM | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|ARM.Build.0 = Release|ARM | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|ARM.Deploy.0 = Release|ARM | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhone.ActiveCfg = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhone.Build.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhone.Deploy.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|iPhoneSimulator.Deploy.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x64.ActiveCfg = Release|x64 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x64.Build.0 = Release|x64 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x64.Deploy.0 = Release|x64 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x86.ActiveCfg = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x86.Build.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Ad-Hoc|x86.Deploy.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|Any CPU.ActiveCfg = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|Any CPU.Build.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|Any CPU.Deploy.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|ARM.ActiveCfg = Release|ARM | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|ARM.Build.0 = Release|ARM | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|ARM.Deploy.0 = Release|ARM | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhone.ActiveCfg = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhone.Build.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhone.Deploy.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhoneSimulator.ActiveCfg = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhoneSimulator.Build.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|iPhoneSimulator.Deploy.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x64.ActiveCfg = Release|x64 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x64.Build.0 = Release|x64 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x64.Deploy.0 = Release|x64 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x86.ActiveCfg = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x86.Build.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.AppStore|x86.Deploy.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|Any CPU.ActiveCfg = Debug|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|Any CPU.Build.0 = Debug|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|Any CPU.Deploy.0 = Debug|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|ARM.ActiveCfg = Debug|ARM | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|ARM.Build.0 = Debug|ARM | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|ARM.Deploy.0 = Debug|ARM | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhone.ActiveCfg = Debug|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|iPhoneSimulator.ActiveCfg = Debug|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x64.ActiveCfg = Debug|x64 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x64.Build.0 = Debug|x64 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x64.Deploy.0 = Debug|x64 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x86.ActiveCfg = Debug|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x86.Build.0 = Debug|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Debug|x86.Deploy.0 = Debug|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|Any CPU.ActiveCfg = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|ARM.ActiveCfg = Release|ARM | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|ARM.Build.0 = Release|ARM | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|ARM.Deploy.0 = Release|ARM | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|iPhone.ActiveCfg = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|iPhoneSimulator.ActiveCfg = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x64.ActiveCfg = Release|x64 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x64.Build.0 = Release|x64 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x64.Deploy.0 = Release|x64 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x86.ActiveCfg = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x86.Build.0 = Release|x86 | |||
{C3C1E2CF-B1F7-4654-BBDC-50143DB22E0B}.Release|x86.Deploy.0 = Release|x86 | |||
EndGlobalSection | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
EndGlobalSection | |||
EndGlobal |
@ -0,0 +1,120 @@ | |||
using System; | |||
using System.Diagnostics; | |||
using System.Threading.Tasks; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Animations.Base | |||
{ | |||
public abstract class AnimationBase : BindableObject | |||
{ | |||
private bool _isRunning = false; | |||
public static readonly BindableProperty TargetProperty = | |||
BindableProperty.Create("Target", typeof(VisualElement), typeof(AnimationBase), null, | |||
propertyChanged: (bindable, oldValue, newValue) => | |||
((AnimationBase)bindable).Target = (VisualElement)newValue); | |||
public VisualElement Target | |||
{ | |||
get { return (VisualElement)GetValue(TargetProperty); } | |||
set { SetValue(TargetProperty, value); } | |||
} | |||
public static readonly BindableProperty DurationProperty = | |||
BindableProperty.Create("Duration", typeof(string), typeof(AnimationBase), "1000", | |||
propertyChanged: (bindable, oldValue, newValue) => | |||
((AnimationBase)bindable).Duration = (string)newValue); | |||
public string Duration | |||
{ | |||
get { return (string)GetValue(DurationProperty); } | |||
set { SetValue(DurationProperty, value); } | |||
} | |||
public static readonly BindableProperty EasingProperty = | |||
BindableProperty.Create("Easing", typeof(EasingType), typeof(AnimationBase), EasingType.Linear, | |||
propertyChanged: (bindable, oldValue, newValue) => | |||
((AnimationBase)bindable).Easing = (EasingType)newValue); | |||
public EasingType Easing | |||
{ | |||
get { return (EasingType)GetValue(EasingProperty); } | |||
set { SetValue(EasingProperty, value); } | |||
} | |||
public static readonly BindableProperty RepeatForeverProperty = | |||
BindableProperty.Create("RepeatForever", typeof(bool), typeof(AnimationBase), false, | |||
propertyChanged: (bindable, oldValue, newValue) => | |||
((AnimationBase)bindable).RepeatForever = (bool)newValue); | |||
public bool RepeatForever | |||
{ | |||
get { return (bool)GetValue(RepeatForeverProperty); } | |||
set { SetValue(RepeatForeverProperty, value); } | |||
} | |||
public static readonly BindableProperty DelayProperty = | |||
BindableProperty.Create("Delay", typeof(int), typeof(AnimationBase), 0, | |||
propertyChanged: (bindable, oldValue, newValue) => | |||
((AnimationBase)bindable).Delay = (int)newValue); | |||
public int Delay | |||
{ | |||
get { return (int)GetValue(DelayProperty); } | |||
set { SetValue(DelayProperty, value); } | |||
} | |||
protected abstract Task BeginAnimation(); | |||
public async Task Begin() | |||
{ | |||
try | |||
{ | |||
if (!_isRunning) | |||
{ | |||
_isRunning = true; | |||
await InternalBegin() | |||
.ContinueWith(t => t.Exception, TaskContinuationOptions.OnlyOnFaulted) | |||
.ConfigureAwait(false); | |||
} | |||
} | |||
catch (TaskCanceledException) | |||
{ | |||
} | |||
catch (Exception ex) | |||
{ | |||
Debug.WriteLine($"Exception in animation {ex}"); | |||
} | |||
} | |||
protected abstract Task ResetAnimation(); | |||
public async Task Reset() | |||
{ | |||
await ResetAnimation(); | |||
} | |||
private async Task InternalBegin() | |||
{ | |||
if (Delay > 0) | |||
{ | |||
await Task.Delay(Delay); | |||
} | |||
if (!RepeatForever) | |||
{ | |||
await BeginAnimation(); | |||
} | |||
else | |||
{ | |||
do | |||
{ | |||
await BeginAnimation(); | |||
await ResetAnimation(); | |||
} while (RepeatForever); | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,17 @@ | |||
namespace eShopOnContainers.Core.Animations.Base | |||
{ | |||
public enum EasingType | |||
{ | |||
BounceIn, | |||
BounceOut, | |||
CubicIn, | |||
CubicInOut, | |||
CubicOut, | |||
Linear, | |||
SinIn, | |||
SinInOut, | |||
SinOut, | |||
SpringIn, | |||
SpringOut | |||
} | |||
} |
@ -0,0 +1,163 @@ | |||
using eShopOnContainers.Core.Animations.Base; | |||
using eShopOnContainers.Core.Helpers; | |||
using System; | |||
using System.Threading.Tasks; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Animations | |||
{ | |||
public class FadeToAnimation : AnimationBase | |||
{ | |||
public static readonly BindableProperty OpacityProperty = | |||
BindableProperty.Create("Opacity", typeof(double), typeof(FadeToAnimation), 0.0d, | |||
propertyChanged: (bindable, oldValue, newValue) => | |||
((FadeToAnimation)bindable).Opacity = (double)newValue); | |||
public double Opacity | |||
{ | |||
get { return (double)GetValue(OpacityProperty); } | |||
set { SetValue(OpacityProperty, value); } | |||
} | |||
protected override Task BeginAnimation() | |||
{ | |||
if (Target == null) | |||
{ | |||
throw new NullReferenceException("Null Target property."); | |||
} | |||
return Target.FadeTo(Opacity, Convert.ToUInt32(Duration), EasingHelper.GetEasing(Easing)); | |||
} | |||
protected override Task ResetAnimation() | |||
{ | |||
if (Target == null) | |||
{ | |||
throw new NullReferenceException("Null Target property."); | |||
} | |||
return Target.FadeTo(0, 0, null); | |||
} | |||
} | |||
public class FadeInAnimation : AnimationBase | |||
{ | |||
public enum FadeDirection | |||
{ | |||
Up, | |||
Down | |||
} | |||
public static readonly BindableProperty DirectionProperty = | |||
BindableProperty.Create("Direction", typeof(FadeDirection), typeof(FadeInAnimation), FadeDirection.Up, | |||
propertyChanged: (bindable, oldValue, newValue) => | |||
((FadeInAnimation)bindable).Direction = (FadeDirection)newValue); | |||
public FadeDirection Direction | |||
{ | |||
get { return (FadeDirection)GetValue(DirectionProperty); } | |||
set { SetValue(DirectionProperty, value); } | |||
} | |||
protected override Task BeginAnimation() | |||
{ | |||
if (Target == null) | |||
{ | |||
throw new NullReferenceException("Null Target property."); | |||
} | |||
return Task.Run(() => | |||
{ | |||
Device.BeginInvokeOnMainThread(() => | |||
{ | |||
Target.Animate("FadeIn", FadeIn(), 16, Convert.ToUInt32(Duration)); | |||
}); | |||
}); | |||
} | |||
protected override Task ResetAnimation() | |||
{ | |||
if (Target == null) | |||
{ | |||
throw new NullReferenceException("Null Target property."); | |||
} | |||
return Target.FadeTo(0, 0, null); | |||
} | |||
internal Animation FadeIn() | |||
{ | |||
var animation = new Animation(); | |||
animation.WithConcurrent((f) => Target.Opacity = f, 0, 1, Xamarin.Forms.Easing.CubicOut); | |||
animation.WithConcurrent( | |||
(f) => Target.TranslationY = f, | |||
Target.TranslationY + ((Direction == FadeDirection.Up) ? 50 : -50), Target.TranslationY, | |||
Xamarin.Forms.Easing.CubicOut, 0, 1); | |||
return animation; | |||
} | |||
} | |||
public class FadeOutAnimation : AnimationBase | |||
{ | |||
public enum FadeDirection | |||
{ | |||
Up, | |||
Down | |||
} | |||
public static readonly BindableProperty DirectionProperty = | |||
BindableProperty.Create("Direction", typeof(FadeDirection), typeof(FadeOutAnimation), FadeDirection.Up, | |||
propertyChanged: (bindable, oldValue, newValue) => | |||
((FadeOutAnimation)bindable).Direction = (FadeDirection)newValue); | |||
public FadeDirection Direction | |||
{ | |||
get { return (FadeDirection)GetValue(DirectionProperty); } | |||
set { SetValue(DirectionProperty, value); } | |||
} | |||
protected override Task BeginAnimation() | |||
{ | |||
if (Target == null) | |||
{ | |||
throw new NullReferenceException("Null Target property."); | |||
} | |||
return Task.Run(() => | |||
{ | |||
Device.BeginInvokeOnMainThread(() => | |||
{ | |||
Target.Animate("FadeOut", FadeOut(), 16, Convert.ToUInt32(Duration)); | |||
}); | |||
}); | |||
} | |||
protected override Task ResetAnimation() | |||
{ | |||
if (Target == null) | |||
{ | |||
throw new NullReferenceException("Null Target property."); | |||
} | |||
return Target.FadeTo(0, 0, null); | |||
} | |||
internal Animation FadeOut() | |||
{ | |||
var animation = new Animation(); | |||
animation.WithConcurrent( | |||
(f) => Target.Opacity = f, | |||
1, 0); | |||
animation.WithConcurrent( | |||
(f) => Target.TranslationY = f, | |||
Target.TranslationY, Target.TranslationY + ((Direction == FadeDirection.Up) ? 50 : -50)); | |||
return animation; | |||
} | |||
} | |||
} |
@ -0,0 +1,48 @@ | |||
using eShopOnContainers.Core.Animations.Base; | |||
using System.Collections.Generic; | |||
using System.Threading.Tasks; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Animations | |||
{ | |||
[ContentProperty("Animations")] | |||
public class StoryBoard : AnimationBase | |||
{ | |||
public StoryBoard() | |||
{ | |||
Animations = new List<AnimationBase>(); | |||
} | |||
public StoryBoard(List<AnimationBase> animations) | |||
{ | |||
Animations = animations; | |||
} | |||
public List<AnimationBase> Animations | |||
{ | |||
get; | |||
} | |||
protected override async Task BeginAnimation() | |||
{ | |||
foreach (var animation in Animations) | |||
{ | |||
if (animation.Target == null) | |||
animation.Target = Target; | |||
await animation.Begin(); | |||
} | |||
} | |||
protected override async Task ResetAnimation() | |||
{ | |||
foreach (var animation in Animations) | |||
{ | |||
if (animation.Target == null) | |||
animation.Target = Target; | |||
await animation.Reset(); | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,140 @@ | |||
<?xml version="1.0" encoding="utf-8" ?> | |||
<Application xmlns="http://xamarin.com/schemas/2014/forms" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | |||
xmlns:light="clr-namespace:Xamarin.Forms.Themes;assembly=Xamarin.Forms.Theme.Light" | |||
xmlns:converters="clr-namespace:eShopOnContainers.Core.Converters;assembly=eShopOnContainers.Core" | |||
xmlns:effects="clr-namespace:eShopOnContainers.Core.Effects;assembly=eShopOnContainers.Core" | |||
x:Class="eShopOnContainers.App"> | |||
<Application.Resources> | |||
<ResourceDictionary MergedWith="light:LightThemeResources"> | |||
<!-- COLORS --> | |||
<Color x:Key="WhiteColor">#ffffff</Color> | |||
<Color x:Key="BlackColor">#000000</Color> | |||
<Color x:Key="BackgroundColor">#F4F6FA</Color> | |||
<Color x:Key="AccentColor">#00857D</Color> | |||
<Color x:Key="LightGreenColor">#83D01B</Color> | |||
<Color x:Key="GreenColor">#00A69C</Color> | |||
<Color x:Key="DarkGreenColor">#00857D</Color> | |||
<Color x:Key="GrayColor">#e2e2e2</Color> | |||
<!-- FONTS --> | |||
<OnPlatform | |||
x:Key="MontserratRegular" | |||
x:TypeArguments="x:String" | |||
iOS="Montserrat-Regular" | |||
Android="Montserrat-Regular.ttf#Montserrat" | |||
WinPhone="Assets/Fonts/Montserrat-Regular.ttf#Montserrat"/> | |||
<OnPlatform | |||
x:Key="MontserratBold" | |||
x:TypeArguments="x:String" | |||
iOS="Montserrat-Bold" | |||
Android="Montserrat-Bold.ttf#Montserrat" | |||
WinPhone="Assets/Fonts/Montserrat-Bold.ttf#Montserrat"/> | |||
<OnPlatform | |||
x:Key="SourceSansProRegular" | |||
x:TypeArguments="x:String" | |||
iOS="SourceSansPro-Regular" | |||
Android="SourceSansPro-Regular.ttf#Source Sans Pro" | |||
WinPhone="Assets/Fonts/SourceSansPro-Regular.ttf#Source Sans Pro"/> | |||
<!-- FONT SIZES --> | |||
<OnPlatform | |||
x:Key="LittleSize" | |||
x:TypeArguments="x:Double" | |||
iOS="11" | |||
Android="12" | |||
WinPhone="12"/> | |||
<OnPlatform | |||
x:Key="MidMediumSize" | |||
x:TypeArguments="x:Double" | |||
iOS="12" | |||
Android="14" | |||
WinPhone="14"/> | |||
<OnPlatform | |||
x:Key="MediumSize" | |||
x:TypeArguments="x:Double" | |||
iOS="14" | |||
Android="16" | |||
WinPhone="16"/> | |||
<OnPlatform | |||
x:Key="LargeSize" | |||
x:TypeArguments="x:Double" | |||
iOS="16" | |||
Android="18" | |||
WinPhone="18"/> | |||
<OnPlatform | |||
x:Key="LargerSize" | |||
x:TypeArguments="x:Double" | |||
iOS="18" | |||
Android="20" | |||
WinPhone="20"/> | |||
<OnPlatform | |||
x:Key="BigSize" | |||
x:TypeArguments="x:Double" | |||
iOS="20" | |||
Android="24" | |||
WinPhone="24"/> | |||
<OnPlatform | |||
x:Key="ExtraBigSize" | |||
x:TypeArguments="x:Double" | |||
iOS="24" | |||
Android="32" | |||
WinPhone="32"/> | |||
<OnPlatform | |||
x:Key="HugeSize" | |||
x:TypeArguments="x:Double" | |||
iOS="32" | |||
Android="48" | |||
WinPhone="48"/> | |||
<!-- CONVERTERS --> | |||
<converters:ToUpperConverter x:Key="ToUpperConverter" /> | |||
<converters:DatetimeConverter x:Key="DatetimeConverter" /> | |||
<!-- STYLES --> | |||
<Style x:Key="EntryStyle" | |||
TargetType="{x:Type Entry}"> | |||
<Setter Property="FontFamily" | |||
Value="{StaticResource MontserratRegular}" /> | |||
<Setter Property="TextColor" | |||
Value="{StaticResource WhiteColor}" /> | |||
<Setter Property="PlaceholderColor" | |||
Value="{StaticResource WhiteColor}" /> | |||
<Setter Property="FontSize" | |||
Value="{StaticResource LargeSize}" /> | |||
<Setter Property="HorizontalOptions" | |||
Value="FillAndExpand" /> | |||
<Setter Property="FontAttributes" | |||
Value="Bold" /> | |||
<Setter Property="Opacity" | |||
Value="0.6" /> | |||
<Setter Property="effects:LineColorEffect.ApplyLineColor" | |||
Value="True" /> | |||
<Setter Property="effects:LineColorEffect.LineColor" | |||
Value="{StaticResource WhiteColor}" /> | |||
<Style.Triggers> | |||
<Trigger TargetType="Entry" | |||
Property="IsFocused" | |||
Value="True"> | |||
<Setter Property="Opacity" Value="1" /> | |||
</Trigger> | |||
</Style.Triggers> | |||
</Style> | |||
<Style TargetType="NavigationPage"> | |||
<Setter Property="BarBackgroundColor" Value="{StaticResource GreenColor}"/> | |||
<Setter Property="BarTextColor" Value="{StaticResource WhiteColor}"/> | |||
</Style> | |||
</ResourceDictionary> | |||
</Application.Resources> | |||
</Application> |
@ -0,0 +1,48 @@ | |||
using eShopOnContainers.Services; | |||
using eShopOnContainers.ViewModels.Base; | |||
using System.Threading.Tasks; | |||
using Xamarin.Forms; | |||
using Xamarin.Forms.Xaml; | |||
[assembly: XamlCompilation(XamlCompilationOptions.Compile)] | |||
namespace eShopOnContainers | |||
{ | |||
public partial class App : Application | |||
{ | |||
public App() | |||
{ | |||
InitializeComponent(); | |||
if (Device.OS == TargetPlatform.Windows) | |||
{ | |||
InitNavigation(); | |||
} | |||
} | |||
private Task InitNavigation() | |||
{ | |||
var navigationService = ViewModelLocator.Instance.Resolve<INavigationService>(); | |||
return navigationService.InitializeAsync(); | |||
} | |||
protected override async void OnStart() | |||
{ | |||
base.OnStart(); | |||
if (Device.OS != TargetPlatform.Windows) | |||
{ | |||
await InitNavigation(); | |||
} | |||
} | |||
protected override void OnSleep() | |||
{ | |||
// Handle when your app sleeps | |||
} | |||
protected override void OnResume() | |||
{ | |||
// Handle when your app resumes | |||
} | |||
} | |||
} |
@ -0,0 +1,111 @@ | |||
using System; | |||
using System.Collections; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Controls | |||
{ | |||
public class BindablePicker : Picker | |||
{ | |||
public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create("ItemsSource", | |||
typeof(IEnumerable), typeof(BindablePicker), null, propertyChanged: OnItemsSourceChanged); | |||
public static readonly BindableProperty SelectedItemProperty = BindableProperty.Create("SelectedItem", | |||
typeof(object), typeof(BindablePicker), null, BindingMode.TwoWay, propertyChanged: OnSelectedItemChanged); | |||
public BindablePicker() | |||
{ | |||
SelectedIndexChanged += (o, e) => | |||
{ | |||
if (SelectedIndex < 0 || ItemsSource == null || !ItemsSource.GetEnumerator().MoveNext()) | |||
{ | |||
SelectedItem = null; | |||
return; | |||
} | |||
var index = 0; | |||
foreach (var item in ItemsSource) | |||
{ | |||
if (index == SelectedIndex) | |||
{ | |||
SelectedItem = item; | |||
break; | |||
} | |||
index++; | |||
} | |||
}; | |||
} | |||
public IEnumerable ItemsSource | |||
{ | |||
get { return (IEnumerable)GetValue(ItemsSourceProperty); } | |||
set { SetValue(ItemsSourceProperty, value); } | |||
} | |||
public Object SelectedItem | |||
{ | |||
get { return GetValue(SelectedItemProperty); } | |||
set | |||
{ | |||
if (SelectedItem != value) | |||
{ | |||
SetValue(SelectedItemProperty, value); | |||
InternalUpdateSelectedIndex(); | |||
} | |||
} | |||
} | |||
public event EventHandler<SelectedItemChangedEventArgs> ItemSelected; | |||
private void InternalUpdateSelectedIndex() | |||
{ | |||
var selectedIndex = -1; | |||
if (ItemsSource != null) | |||
{ | |||
var index = 0; | |||
foreach (var item in ItemsSource) | |||
{ | |||
string strItem = item?.ToString(); | |||
if (item != null && SelectedItem != null | |||
&& !string.IsNullOrEmpty(strItem) | |||
&& item.ToString().Equals(SelectedItem.ToString())) | |||
{ | |||
selectedIndex = index; | |||
break; | |||
} | |||
index++; | |||
} | |||
} | |||
SelectedIndex = selectedIndex; | |||
} | |||
private static void OnItemsSourceChanged(BindableObject bindable, object oldValue, object newValue) | |||
{ | |||
var boundPicker = (BindablePicker)bindable; | |||
if (Equals(newValue, null) && !Equals(oldValue, null)) | |||
return; | |||
boundPicker.Items.Clear(); | |||
if (!Equals(newValue, null)) | |||
{ | |||
foreach (var item in (IEnumerable)newValue) | |||
boundPicker.Items.Add(item.ToString()); | |||
} | |||
boundPicker.InternalUpdateSelectedIndex(); | |||
} | |||
private static void OnSelectedItemChanged(BindableObject bindable, object oldValue, object newValue) | |||
{ | |||
var boundPicker = (BindablePicker)bindable; | |||
if (boundPicker.ItemSelected != null) | |||
{ | |||
boundPicker.ItemSelected(boundPicker, new SelectedItemChangedEventArgs(newValue)); | |||
} | |||
boundPicker.InternalUpdateSelectedIndex(); | |||
} | |||
} | |||
} |
@ -0,0 +1,35 @@ | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Controls | |||
{ | |||
public class CustomTabbedPage : TabbedPage | |||
{ | |||
public static BindableProperty BadgeTextProperty = | |||
BindableProperty.CreateAttached("BadgeText", typeof(string), typeof(CustomTabbedPage), default(string), | |||
BindingMode.OneWay); | |||
public static BindableProperty BadgeColorProperty = | |||
BindableProperty.CreateAttached("BadgeColor", typeof(Color), typeof(CustomTabbedPage), Color.Default, | |||
BindingMode.OneWay); | |||
public static string GetBadgeText(BindableObject view) | |||
{ | |||
return (string)view.GetValue(BadgeTextProperty); | |||
} | |||
public static void SetBadgeText(BindableObject view, string value) | |||
{ | |||
view.SetValue(BadgeTextProperty, value); | |||
} | |||
public static Color GetBadgeColor(BindableObject view) | |||
{ | |||
return (Color)view.GetValue(BadgeColorProperty); | |||
} | |||
public static void SetBadgeColor(BindableObject view, Color value) | |||
{ | |||
view.SetValue(BadgeColorProperty, value); | |||
} | |||
} | |||
} |
@ -0,0 +1,26 @@ | |||
using System; | |||
using System.Globalization; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Converters | |||
{ | |||
public class DatetimeConverter : IValueConverter | |||
{ | |||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | |||
{ | |||
if(value is DateTime) | |||
{ | |||
var date = (DateTime)value; | |||
return date.ToString("MMMM dd yyyy").ToUpper(); | |||
} | |||
return value; | |||
} | |||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
} | |||
} |
@ -0,0 +1,19 @@ | |||
using System; | |||
using System.Globalization; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Converters | |||
{ | |||
public class ToUpperConverter : IValueConverter | |||
{ | |||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | |||
{ | |||
return value.ToString().ToUpperInvariant(); | |||
} | |||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
} | |||
} |
@ -0,0 +1,67 @@ | |||
using System.Linq; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Effects | |||
{ | |||
public static class LineColorEffect | |||
{ | |||
public static readonly BindableProperty ApplyLineColorProperty = | |||
BindableProperty.CreateAttached("ApplyLineColor", typeof(bool), typeof(LineColorEffect), false, | |||
propertyChanged: OnApplyLineColorChanged); | |||
public static bool GetApplyLineColor(BindableObject view) | |||
{ | |||
return (bool)view.GetValue(ApplyLineColorProperty); | |||
} | |||
public static void SetApplyLineColor(BindableObject view, bool value) | |||
{ | |||
view.SetValue(ApplyLineColorProperty, value); | |||
} | |||
private static void OnApplyLineColorChanged(BindableObject bindable, object oldValue, object newValue) | |||
{ | |||
var view = bindable as View; | |||
if (view == null) | |||
{ | |||
return; | |||
} | |||
bool hasShadow = (bool)newValue; | |||
if (hasShadow) | |||
{ | |||
view.Effects.Add(new EntryLineColorEffect()); | |||
} | |||
else | |||
{ | |||
var entryLineColorEffectToRemove = view.Effects.FirstOrDefault(e => e is EntryLineColorEffect); | |||
if (entryLineColorEffectToRemove != null) | |||
{ | |||
view.Effects.Remove(entryLineColorEffectToRemove); | |||
} | |||
} | |||
} | |||
public static readonly BindableProperty LineColorProperty = | |||
BindableProperty.CreateAttached("LineColor", typeof(Color), typeof(LineColorEffect), Color.Default); | |||
public static Color GetLineColor(BindableObject view) | |||
{ | |||
return (Color)view.GetValue(LineColorProperty); | |||
} | |||
public static void SetLineColor(BindableObject view, Color value) | |||
{ | |||
view.SetValue(LineColorProperty, value); | |||
} | |||
class EntryLineColorEffect : RoutingEffect | |||
{ | |||
public EntryLineColorEffect() : base("BikeSharing.EntryLineColorEffect") | |||
{ | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,18 @@ | |||
using eShopOnContainers.Core.Animations.Base; | |||
using System; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Extensions | |||
{ | |||
public static class AnimationExtension | |||
{ | |||
public static async void Animate(this VisualElement visualElement, AnimationBase animation, Action onFinishedCallback = null) | |||
{ | |||
animation.Target = visualElement; | |||
await animation.Begin(); | |||
onFinishedCallback?.Invoke(); | |||
} | |||
} | |||
} |
@ -0,0 +1,39 @@ | |||
using eShopOnContainers.Core.Animations.Base; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Helpers | |||
{ | |||
public static class EasingHelper | |||
{ | |||
public static Easing GetEasing(EasingType type) | |||
{ | |||
switch (type) | |||
{ | |||
case EasingType.BounceIn: | |||
return Easing.BounceIn; | |||
case EasingType.BounceOut: | |||
return Easing.BounceOut; | |||
case EasingType.CubicIn: | |||
return Easing.CubicIn; | |||
case EasingType.CubicInOut: | |||
return Easing.CubicInOut; | |||
case EasingType.CubicOut: | |||
return Easing.CubicOut; | |||
case EasingType.Linear: | |||
return Easing.Linear; | |||
case EasingType.SinIn: | |||
return Easing.SinIn; | |||
case EasingType.SinInOut: | |||
return Easing.SinInOut; | |||
case EasingType.SinOut: | |||
return Easing.SinOut; | |||
case EasingType.SpringIn: | |||
return Easing.SpringIn; | |||
case EasingType.SpringOut: | |||
return Easing.SpringOut; | |||
} | |||
return null; | |||
} | |||
} | |||
} |
@ -0,0 +1,12 @@ | |||
using System; | |||
namespace eShopOnContainers.Core.Models.Orders | |||
{ | |||
public class Order | |||
{ | |||
public long OrderNumber { get; set; } | |||
public double Total { get; set; } | |||
public DateTime Date { get; set; } | |||
public OrderStatus Status { get; set; } | |||
} | |||
} |
@ -0,0 +1,10 @@ | |||
namespace eShopOnContainers.Core.Models.Orders | |||
{ | |||
public enum OrderStatus | |||
{ | |||
Pending, | |||
WareHouse, | |||
Delivered, | |||
Lost | |||
} | |||
} |
@ -0,0 +1,9 @@ | |||
namespace eShopOnContainers.Core.Models.Products | |||
{ | |||
public class Product | |||
{ | |||
public string Name { get; set; } | |||
public string Image { get; set; } | |||
public double Price { get; set; } | |||
} | |||
} |
@ -0,0 +1,30 @@ | |||
using System.Resources; | |||
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("eShopOnContainers")] | |||
[assembly: AssemblyDescription("")] | |||
[assembly: AssemblyConfiguration("")] | |||
[assembly: AssemblyCompany("")] | |||
[assembly: AssemblyProduct("eShopOnContainers")] | |||
[assembly: AssemblyCopyright("Copyright © 2016")] | |||
[assembly: AssemblyTrademark("")] | |||
[assembly: AssemblyCulture("")] | |||
[assembly: NeutralResourcesLanguage("en")] | |||
// 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")] |
@ -0,0 +1,13 @@ | |||
using Acr.UserDialogs; | |||
using System.Threading.Tasks; | |||
namespace eShopOnContainers.Services | |||
{ | |||
public class DialogService : IDialogService | |||
{ | |||
public Task ShowAlertAsync(string message, string title, string buttonLabel) | |||
{ | |||
return UserDialogs.Instance.AlertAsync(message, title, buttonLabel); | |||
} | |||
} | |||
} |
@ -0,0 +1,9 @@ | |||
using System.Threading.Tasks; | |||
namespace eShopOnContainers.Services | |||
{ | |||
public interface IDialogService | |||
{ | |||
Task ShowAlertAsync(string message, string title, string buttonLabel); | |||
} | |||
} |
@ -0,0 +1,25 @@ | |||
using eShopOnContainers.ViewModels.Base; | |||
using System; | |||
using System.Threading.Tasks; | |||
namespace eShopOnContainers.Services | |||
{ | |||
public interface INavigationService | |||
{ | |||
Task InitializeAsync(); | |||
Task NavigateToAsync<TViewModel>() where TViewModel : ViewModelBase; | |||
Task NavigateToAsync<TViewModel>(object parameter) where TViewModel : ViewModelBase; | |||
Task NavigateToAsync(Type viewModelType); | |||
Task NavigateToAsync(Type viewModelType, object parameter); | |||
Task NavigateBackAsync(); | |||
Task RemoveLastFromBackStackAsync(); | |||
Task RemoveBackStackAsync(); | |||
} | |||
} |
@ -0,0 +1,159 @@ | |||
using eShopOnContainers.Core.ViewModels; | |||
using eShopOnContainers.Core.Views; | |||
using eShopOnContainers.ViewModels.Base; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Threading.Tasks; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Services | |||
{ | |||
public class NavigationService : INavigationService | |||
{ | |||
protected readonly Dictionary<Type, Type> _mappings; | |||
protected Application CurrentApplication | |||
{ | |||
get | |||
{ | |||
return Application.Current; | |||
} | |||
} | |||
public NavigationService() | |||
{ | |||
_mappings = new Dictionary<Type, Type>(); | |||
CreatePageViewModelMappings(); | |||
} | |||
public Task InitializeAsync() | |||
{ | |||
return NavigateToAsync<LoginViewModel>(); | |||
} | |||
public Task NavigateToAsync<TViewModel>() where TViewModel : ViewModelBase | |||
{ | |||
return InternalNavigateToAsync(typeof(TViewModel), null); | |||
} | |||
public Task NavigateToAsync<TViewModel>(object parameter) where TViewModel : ViewModelBase | |||
{ | |||
return InternalNavigateToAsync(typeof(TViewModel), parameter); | |||
} | |||
public Task NavigateToAsync(Type viewModelType) | |||
{ | |||
return InternalNavigateToAsync(viewModelType, null); | |||
} | |||
public Task NavigateToAsync(Type viewModelType, object parameter) | |||
{ | |||
return InternalNavigateToAsync(viewModelType, parameter); | |||
} | |||
public async Task NavigateBackAsync() | |||
{ | |||
if (CurrentApplication.MainPage is HomeView) | |||
{ | |||
var mainPage = CurrentApplication.MainPage as HomeView; | |||
await mainPage.Navigation.PopAsync(); | |||
} | |||
else if (CurrentApplication.MainPage != null) | |||
{ | |||
await CurrentApplication.MainPage.Navigation.PopAsync(); | |||
} | |||
} | |||
public virtual Task RemoveLastFromBackStackAsync() | |||
{ | |||
var mainPage = CurrentApplication.MainPage as CustomNavigationPage; | |||
if (mainPage != null) | |||
{ | |||
mainPage.Navigation.RemovePage( | |||
mainPage.Navigation.NavigationStack[mainPage.Navigation.NavigationStack.Count - 2]); | |||
} | |||
return Task.FromResult(true); | |||
} | |||
public virtual Task RemoveBackStackAsync() | |||
{ | |||
var mainPage = CurrentApplication.MainPage as CustomNavigationPage; | |||
if (mainPage != null) | |||
{ | |||
for (int i = 0; i < mainPage.Navigation.NavigationStack.Count - 1; i++) | |||
{ | |||
var page = mainPage.Navigation.NavigationStack[i]; | |||
mainPage.Navigation.RemovePage(page); | |||
} | |||
} | |||
return Task.FromResult(true); | |||
} | |||
protected virtual async Task InternalNavigateToAsync(Type viewModelType, object parameter) | |||
{ | |||
Page page = CreateAndBindPage(viewModelType, parameter); | |||
if (page is LoginView) | |||
{ | |||
CurrentApplication.MainPage = new CustomNavigationPage(page); | |||
} | |||
else | |||
{ | |||
var navigationPage = CurrentApplication.MainPage as CustomNavigationPage; | |||
if (navigationPage != null) | |||
{ | |||
await navigationPage.PushAsync(page); | |||
} | |||
else | |||
{ | |||
CurrentApplication.MainPage = new CustomNavigationPage(page); | |||
} | |||
} | |||
await (page.BindingContext as ViewModelBase).InitializeAsync(parameter); | |||
} | |||
protected Type GetPageTypeForViewModel(Type viewModelType) | |||
{ | |||
if (!_mappings.ContainsKey(viewModelType)) | |||
{ | |||
throw new KeyNotFoundException($"No map for ${viewModelType} was found on navigation mappings"); | |||
} | |||
return _mappings[viewModelType]; | |||
} | |||
protected Page CreateAndBindPage(Type viewModelType, object parameter) | |||
{ | |||
Type pageType = GetPageTypeForViewModel(viewModelType); | |||
if (pageType == null) | |||
{ | |||
throw new Exception($"Mapping type for {viewModelType} is not a page"); | |||
} | |||
Page page = Activator.CreateInstance(pageType) as Page; | |||
ViewModelBase viewModel = ViewModelLocator.Instance.Resolve(viewModelType) as ViewModelBase; | |||
page.BindingContext = viewModel; | |||
return page; | |||
} | |||
private void CreatePageViewModelMappings() | |||
{ | |||
_mappings.Add(typeof(CartViewModel), typeof(CartView)); | |||
_mappings.Add(typeof(ProductsViewModel), typeof(HomeView)); | |||
_mappings.Add(typeof(LoginViewModel), typeof(LoginView)); | |||
_mappings.Add(typeof(MainViewModel), typeof(MainView)); | |||
_mappings.Add(typeof(OrderDetailViewModel), typeof(OrderDetailView)); | |||
_mappings.Add(typeof(OrdersViewModel), typeof(OrdersView)); | |||
_mappings.Add(typeof(ProfileViewModel), typeof(ProfileView)); | |||
} | |||
} | |||
} |
@ -0,0 +1,29 @@ | |||
using eShopOnContainers.Core.Models.Orders; | |||
using System; | |||
using System.Collections.ObjectModel; | |||
using System.Threading.Tasks; | |||
namespace eShopOnContainers.Core.Services.Orders | |||
{ | |||
public class FakeOrdersService : IOrdersService | |||
{ | |||
public async Task<ObservableCollection<Order>> GetOrdersAsync() | |||
{ | |||
await Task.Delay(500); | |||
return new ObservableCollection<Order> | |||
{ | |||
new Order { OrderNumber = 0123456789, Total = 45.30, Date = DateTime.Now, Status = OrderStatus.Delivered }, | |||
new Order { OrderNumber = 9123456780, Total = 39.95, Date = DateTime.Now, Status = OrderStatus.Delivered }, | |||
new Order { OrderNumber = 8765432190, Total = 15.00, Date = DateTime.Now, Status = OrderStatus.Delivered }, | |||
}; | |||
} | |||
public async Task<Order> GetCartAsync() | |||
{ | |||
await Task.Delay(500); | |||
return new Order { OrderNumber = 0123456789, Total = 45.99, Date = DateTime.Now, Status = OrderStatus.Pending }; | |||
} | |||
} | |||
} |
@ -0,0 +1,13 @@ | |||
using eShopOnContainers.Core.Models.Orders; | |||
using System.Collections.ObjectModel; | |||
using System.Threading.Tasks; | |||
namespace eShopOnContainers.Core.Services.Orders | |||
{ | |||
public interface IOrdersService | |||
{ | |||
Task<ObservableCollection<Order>> GetOrdersAsync(); | |||
Task<Order> GetCartAsync(); | |||
} | |||
} |
@ -0,0 +1,22 @@ | |||
using eShopOnContainers.Core.Models.Products; | |||
using System.Collections.ObjectModel; | |||
using System.Threading.Tasks; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Services.Products | |||
{ | |||
public class FakeProductsService : IProductsService | |||
{ | |||
public async Task<ObservableCollection<Product>> GetProductsAsync() | |||
{ | |||
await Task.Delay(500); | |||
return new ObservableCollection<Product> | |||
{ | |||
new Product { Image = Device.OS != TargetPlatform.Windows ? "fake_product_01" : "Assets/fake_product_01.png", Name = ".NET Bot Blue Sweatshirt (M)", Price = 19.50 }, | |||
new Product { Image = Device.OS != TargetPlatform.Windows ? "fake_product_02": "Assets/fake_product_02.png", Name = ".NET Bot Purple Sweatshirt (M)", Price = 19.50 }, | |||
new Product { Image = Device.OS != TargetPlatform.Windows ? "fake_product_03": "Assets/fake_product_03.png", Name = ".NET Bot Black Sweatshirt (M)", Price = 19.95 } | |||
}; | |||
} | |||
} | |||
} |
@ -0,0 +1,11 @@ | |||
using eShopOnContainers.Core.Models.Products; | |||
using System.Collections.ObjectModel; | |||
using System.Threading.Tasks; | |||
namespace eShopOnContainers.Core.Services.Products | |||
{ | |||
public interface IProductsService | |||
{ | |||
Task<ObservableCollection<Product>> GetProductsAsync(); | |||
} | |||
} |
@ -0,0 +1,16 @@ | |||
using eShopOnContainers.Core.Animations.Base; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Triggers | |||
{ | |||
public class BeginAnimation : TriggerAction<VisualElement> | |||
{ | |||
public AnimationBase Animation { get; set; } | |||
protected override async void Invoke(VisualElement sender) | |||
{ | |||
if (Animation != null) | |||
await Animation.Begin(); | |||
} | |||
} | |||
} |
@ -0,0 +1,9 @@ | |||
namespace eShopOnContainers.Core.Validations | |||
{ | |||
public interface IValidationRule<T> | |||
{ | |||
string ValidationMessage { get; set; } | |||
bool Check(T value); | |||
} | |||
} |
@ -0,0 +1,7 @@ | |||
namespace eShopOnContainers.Core.Validations | |||
{ | |||
public interface IValidity | |||
{ | |||
bool IsValid { get; set; } | |||
} | |||
} |
@ -0,0 +1,19 @@ | |||
namespace eShopOnContainers.Core.Validations | |||
{ | |||
public class IsNotNullOrEmptyRule<T> : IValidationRule<T> | |||
{ | |||
public string ValidationMessage { get; set; } | |||
public bool Check(T value) | |||
{ | |||
if (value == null) | |||
{ | |||
return false; | |||
} | |||
var str = value as string; | |||
return !string.IsNullOrWhiteSpace(str); | |||
} | |||
} | |||
} |
@ -0,0 +1,72 @@ | |||
using eShopOnContainers.ViewModels.Base; | |||
using System.Collections.Generic; | |||
using System.Collections.ObjectModel; | |||
using System.Linq; | |||
namespace eShopOnContainers.Core.Validations | |||
{ | |||
public class ValidatableObject<T> : ExtendedBindableObject, IValidity | |||
{ | |||
private readonly List<IValidationRule<T>> _validations; | |||
private readonly ObservableCollection<string> _errors; | |||
private T _value; | |||
private bool _isValid; | |||
public List<IValidationRule<T>> Validations => _validations; | |||
public ObservableCollection<string> Errors => _errors; | |||
public T Value | |||
{ | |||
get | |||
{ | |||
return _value; | |||
} | |||
set | |||
{ | |||
_value = value; | |||
RaisePropertyChanged(() => Value); | |||
} | |||
} | |||
public bool IsValid | |||
{ | |||
get | |||
{ | |||
return _isValid; | |||
} | |||
set | |||
{ | |||
_isValid = value; | |||
_errors.Clear(); | |||
RaisePropertyChanged(() => IsValid); | |||
} | |||
} | |||
public ValidatableObject() | |||
{ | |||
_isValid = true; | |||
_errors = new ObservableCollection<string>(); | |||
_validations = new List<IValidationRule<T>>(); | |||
} | |||
public bool Validate() | |||
{ | |||
Errors.Clear(); | |||
IEnumerable<string> errors = _validations.Where(v => !v.Check(Value)) | |||
.Select(v => v.ValidationMessage); | |||
foreach (var error in errors) | |||
{ | |||
Errors.Add(error); | |||
} | |||
IsValid = !Errors.Any(); | |||
return this.IsValid; | |||
} | |||
} | |||
} |
@ -0,0 +1,32 @@ | |||
using System; | |||
using System.Linq.Expressions; | |||
using System.Reflection; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.ViewModels.Base | |||
{ | |||
public abstract class ExtendedBindableObject : BindableObject | |||
{ | |||
public void RaisePropertyChanged<T>(Expression<Func<T>> property) | |||
{ | |||
var name = GetMemberInfo(property).Name; | |||
OnPropertyChanged(name); | |||
} | |||
private MemberInfo GetMemberInfo(Expression expression) | |||
{ | |||
MemberExpression operand; | |||
LambdaExpression lambdaExpression = (LambdaExpression)expression; | |||
if (lambdaExpression.Body as UnaryExpression != null) | |||
{ | |||
UnaryExpression body = (UnaryExpression)lambdaExpression.Body; | |||
operand = (MemberExpression)body.Operand; | |||
} | |||
else | |||
{ | |||
operand = (MemberExpression)lambdaExpression.Body; | |||
} | |||
return operand.Member; | |||
} | |||
} | |||
} |
@ -0,0 +1,8 @@ | |||
namespace eShopOnContainers.Core.ViewModels.Base | |||
{ | |||
public class MessengerKeys | |||
{ | |||
// Add product to cart | |||
public const string AddProduct = "AddProduct"; | |||
} | |||
} |
@ -0,0 +1,38 @@ | |||
using eShopOnContainers.Services; | |||
using System.Threading.Tasks; | |||
namespace eShopOnContainers.ViewModels.Base | |||
{ | |||
public abstract class ViewModelBase : ExtendedBindableObject | |||
{ | |||
protected readonly IDialogService DialogService; | |||
protected readonly INavigationService NavigationService; | |||
private bool _isBusy; | |||
public bool IsBusy | |||
{ | |||
get | |||
{ | |||
return _isBusy; | |||
} | |||
set | |||
{ | |||
_isBusy = value; | |||
RaisePropertyChanged(() => IsBusy); | |||
} | |||
} | |||
public ViewModelBase() | |||
{ | |||
DialogService = ViewModelLocator.Instance.Resolve<IDialogService>(); | |||
NavigationService = ViewModelLocator.Instance.Resolve<INavigationService>(); | |||
} | |||
public virtual Task InitializeAsync(object navigationData) | |||
{ | |||
return Task.FromResult(false); | |||
} | |||
} | |||
} |
@ -0,0 +1,69 @@ | |||
using Microsoft.Practices.Unity; | |||
using eShopOnContainers.Core.Services.Orders; | |||
using eShopOnContainers.Core.Services.Products; | |||
using eShopOnContainers.Core.ViewModels; | |||
using eShopOnContainers.Services; | |||
using System; | |||
namespace eShopOnContainers.ViewModels.Base | |||
{ | |||
public class ViewModelLocator | |||
{ | |||
private readonly IUnityContainer _unityContainer; | |||
private static readonly ViewModelLocator _instance = new ViewModelLocator(); | |||
public static ViewModelLocator Instance | |||
{ | |||
get | |||
{ | |||
return _instance; | |||
} | |||
} | |||
protected ViewModelLocator() | |||
{ | |||
_unityContainer = new UnityContainer(); | |||
// services | |||
_unityContainer.RegisterType<IDialogService, DialogService>(); | |||
RegisterSingleton<INavigationService, NavigationService>(); | |||
_unityContainer.RegisterType<IProductsService, FakeProductsService>(); | |||
_unityContainer.RegisterType<IOrdersService, FakeOrdersService>(); | |||
// view models | |||
_unityContainer.RegisterType<CartViewModel>(); | |||
_unityContainer.RegisterType<ProductsViewModel>(); | |||
_unityContainer.RegisterType<LoginViewModel>(); | |||
_unityContainer.RegisterType<MainViewModel>(); | |||
_unityContainer.RegisterType<OrderDetailViewModel>(); | |||
_unityContainer.RegisterType<OrdersViewModel>(); | |||
_unityContainer.RegisterType<ProfileViewModel>(); | |||
} | |||
public T Resolve<T>() | |||
{ | |||
return _unityContainer.Resolve<T>(); | |||
} | |||
public object Resolve(Type type) | |||
{ | |||
return _unityContainer.Resolve(type); | |||
} | |||
public void Register<T>(T instance) | |||
{ | |||
_unityContainer.RegisterInstance<T>(instance); | |||
} | |||
public void Register<TInterface, T>() where T : TInterface | |||
{ | |||
_unityContainer.RegisterType<TInterface, T>(); | |||
} | |||
public void RegisterSingleton<TInterface, T>() where T : TInterface | |||
{ | |||
_unityContainer.RegisterType<TInterface, T>(new ContainerControlledLifetimeManager()); | |||
} | |||
} | |||
} |
@ -0,0 +1,52 @@ | |||
using eShopOnContainers.Core.Models.Orders; | |||
using eShopOnContainers.Core.Services.Orders; | |||
using eShopOnContainers.Core.ViewModels.Base; | |||
using eShopOnContainers.ViewModels.Base; | |||
using System.Threading.Tasks; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.ViewModels | |||
{ | |||
public class CartViewModel : ViewModelBase | |||
{ | |||
private int _badgeCount; | |||
private Order _order; | |||
private IOrdersService _orderService; | |||
public CartViewModel(IOrdersService orderService) | |||
{ | |||
_orderService = orderService; | |||
} | |||
public int BadgeCount | |||
{ | |||
get { return _badgeCount; } | |||
set | |||
{ | |||
_badgeCount = value; | |||
RaisePropertyChanged(() => BadgeCount); | |||
} | |||
} | |||
public Order Order | |||
{ | |||
get { return _order; } | |||
set | |||
{ | |||
_order = value; | |||
RaisePropertyChanged(() => Order); | |||
} | |||
} | |||
public override async Task InitializeAsync(object navigationData) | |||
{ | |||
MessagingCenter.Subscribe<ProductsViewModel>(this, MessengerKeys.AddProduct, (sender) => | |||
{ | |||
BadgeCount++; | |||
}); | |||
Order = await _orderService.GetCartAsync(); | |||
} | |||
} | |||
} |
@ -0,0 +1,111 @@ | |||
using eShopOnContainers.Core.Validations; | |||
using eShopOnContainers.ViewModels.Base; | |||
using System; | |||
using System.Diagnostics; | |||
using System.Windows.Input; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.ViewModels | |||
{ | |||
public class LoginViewModel : ViewModelBase | |||
{ | |||
private ValidatableObject<string> _userName; | |||
private ValidatableObject<string> _password; | |||
private bool _isValid; | |||
public LoginViewModel() | |||
{ | |||
_userName = new ValidatableObject<string>(); | |||
_password = new ValidatableObject<string>(); | |||
AddValidations(); | |||
} | |||
public ValidatableObject<string> UserName | |||
{ | |||
get | |||
{ | |||
return _userName; | |||
} | |||
set | |||
{ | |||
_userName = value; | |||
RaisePropertyChanged(() => UserName); | |||
} | |||
} | |||
public ValidatableObject<string> Password | |||
{ | |||
get | |||
{ | |||
return _password; | |||
} | |||
set | |||
{ | |||
_password = value; | |||
RaisePropertyChanged(() => Password); | |||
} | |||
} | |||
public bool IsValid | |||
{ | |||
get | |||
{ | |||
return _isValid; | |||
} | |||
set | |||
{ | |||
_isValid = value; | |||
RaisePropertyChanged(() => IsValid); | |||
} | |||
} | |||
public ICommand SignInCommand => new Command(SignInAsync); | |||
private async void SignInAsync() | |||
{ | |||
IsBusy = true; | |||
IsValid = true; | |||
bool isValid = Validate(); | |||
bool isAuthenticated = false; | |||
if (isValid) | |||
{ | |||
try | |||
{ | |||
isAuthenticated = true; | |||
} | |||
catch (Exception ex) | |||
{ | |||
Debug.WriteLine($"[SignIn] Error signing in: {ex}"); | |||
} | |||
} | |||
else | |||
{ | |||
IsValid = false; | |||
} | |||
if (isAuthenticated) | |||
{ | |||
await NavigationService.NavigateToAsync<MainViewModel>(); | |||
await NavigationService.RemoveLastFromBackStackAsync(); | |||
} | |||
IsBusy = false; | |||
} | |||
private bool Validate() | |||
{ | |||
bool isValidUser = _userName.Validate(); | |||
bool isValidPassword = _password.Validate(); | |||
return isValidUser && isValidPassword; | |||
} | |||
private void AddValidations() | |||
{ | |||
_userName.Validations.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "Username should not be empty" }); | |||
_password.Validations.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "Password should not be empty" }); | |||
} | |||
} | |||
} |
@ -0,0 +1,9 @@ | |||
using eShopOnContainers.ViewModels.Base; | |||
namespace eShopOnContainers.Core.ViewModels | |||
{ | |||
public class MainViewModel : ViewModelBase | |||
{ | |||
} | |||
} |
@ -0,0 +1,8 @@ | |||
using eShopOnContainers.ViewModels.Base; | |||
namespace eShopOnContainers.Core.ViewModels | |||
{ | |||
public class OrderDetailViewModel : ViewModelBase | |||
{ | |||
} | |||
} |
@ -0,0 +1,8 @@ | |||
using eShopOnContainers.ViewModels.Base; | |||
namespace eShopOnContainers.Core.ViewModels | |||
{ | |||
public class OrdersViewModel : ViewModelBase | |||
{ | |||
} | |||
} |
@ -0,0 +1,45 @@ | |||
using eShopOnContainers.Core.Models.Orders; | |||
using eShopOnContainers.Core.Services.Orders; | |||
using eShopOnContainers.ViewModels.Base; | |||
using System.Collections.ObjectModel; | |||
using System.Threading.Tasks; | |||
using System.Windows.Input; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.ViewModels | |||
{ | |||
public class ProfileViewModel : ViewModelBase | |||
{ | |||
private ObservableCollection<Order> _orders; | |||
private IOrdersService _ordersService; | |||
public ProfileViewModel(IOrdersService ordersService) | |||
{ | |||
_ordersService = ordersService; | |||
} | |||
public ObservableCollection<Order> Orders | |||
{ | |||
get { return _orders; } | |||
set | |||
{ | |||
_orders = value; | |||
RaisePropertyChanged(() => Orders); | |||
} | |||
} | |||
public ICommand LogoutCommand => new Command(LogoutAsync); | |||
public override async Task InitializeAsync(object navigationData) | |||
{ | |||
Orders = await _ordersService.GetOrdersAsync(); | |||
} | |||
private async void LogoutAsync() | |||
{ | |||
await NavigationService.NavigateToAsync<LoginViewModel>(); | |||
await NavigationService.RemoveBackStackAsync(); | |||
} | |||
} | |||
} |
@ -0,0 +1,57 @@ | |||
using System.Threading.Tasks; | |||
using eShopOnContainers.ViewModels.Base; | |||
using eShopOnContainers.Core.Services.Products; | |||
using System.Collections.ObjectModel; | |||
using eShopOnContainers.Core.Models.Products; | |||
using Xamarin.Forms; | |||
using eShopOnContainers.Core.ViewModels.Base; | |||
namespace eShopOnContainers.Core.ViewModels | |||
{ | |||
public class ProductsViewModel : ViewModelBase | |||
{ | |||
private ObservableCollection<Product> _products; | |||
private Product _product; | |||
private IProductsService _productsService; | |||
public ProductsViewModel(IProductsService productsService) | |||
{ | |||
_productsService = productsService; | |||
} | |||
public ObservableCollection<Product> Products | |||
{ | |||
get { return _products; } | |||
set | |||
{ | |||
_products = value; | |||
RaisePropertyChanged(() => Products); | |||
} | |||
} | |||
public Product Product | |||
{ | |||
get { return _product; } | |||
set | |||
{ | |||
_product = value; | |||
if (_product != null) | |||
{ | |||
AddProduct(); | |||
} | |||
} | |||
} | |||
public override async Task InitializeAsync(object navigationData) | |||
{ | |||
Products = await _productsService.GetProductsAsync(); | |||
} | |||
private void AddProduct() | |||
{ | |||
MessagingCenter.Send(this, MessengerKeys.AddProduct); | |||
} | |||
} | |||
} |
@ -0,0 +1,139 @@ | |||
<?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="eShopOnContainers.Core.Views.CartView" | |||
Title="Cart"> | |||
<ContentPage.Resources> | |||
<ResourceDictionary> | |||
<Style x:Key="OrderTitleStyle" | |||
TargetType="{x:Type Label}"> | |||
<Setter Property="FontFamily" | |||
Value="{StaticResource MontserratRegular}" /> | |||
<Setter Property="FontSize" | |||
Value="{StaticResource MediumSize}" /> | |||
<Setter Property="TextColor" | |||
Value="Gray" /> | |||
</Style> | |||
<Style x:Key="OrderContentStyle" | |||
TargetType="{x:Type Label}" | |||
BasedOn="{StaticResource OrderTitleStyle}"> | |||
<Setter Property="TextColor" | |||
Value="Black" /> | |||
</Style> | |||
<Style x:Key="ShippingAddressStyle" | |||
TargetType="{x:Type Label}" | |||
BasedOn="{StaticResource OrderTitleStyle}"> | |||
<Setter Property="FontSize" | |||
Value="{StaticResource LargeSize}" /> | |||
<Setter Property="TextColor" | |||
Value="Black" /> | |||
</Style> | |||
<Style x:Key="AddressStyle" | |||
TargetType="{x:Type Label}" | |||
BasedOn="{StaticResource OrderTitleStyle}"> | |||
<Setter Property="FontSize" | |||
Value="{StaticResource LittleSize}" /> | |||
<Setter Property="TextColor" | |||
Value="Black" /> | |||
</Style> | |||
</ResourceDictionary> | |||
</ContentPage.Resources> | |||
<ScrollView> | |||
<Grid | |||
BackgroundColor="{StaticResource BackgroundColor}"> | |||
<Grid.RowDefinitions> | |||
<RowDefinition /> | |||
<RowDefinition /> | |||
<RowDefinition /> | |||
</Grid.RowDefinitions> | |||
<!-- ORDER INFO --> | |||
<Grid> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition /> | |||
<ColumnDefinition /> | |||
</Grid.ColumnDefinitions> | |||
<Grid.RowDefinitions> | |||
<RowDefinition /> | |||
<RowDefinition /> | |||
</Grid.RowDefinitions> | |||
<StackLayout | |||
Grid.Column="0" | |||
Grid.Row="0" | |||
Margin="12"> | |||
<Label | |||
Text="ORDER NUMBER" | |||
Style="{StaticResource OrderTitleStyle}"/> | |||
<Label | |||
Text="{Binding Order.OrderNumber, Converter={StaticResource ToUpperConverter}}" | |||
Style="{StaticResource OrderContentStyle}"/> | |||
</StackLayout> | |||
<StackLayout | |||
Grid.Column="0" | |||
Grid.Row="1" | |||
Margin="12"> | |||
<Label | |||
Text="TOTAL" | |||
Style="{StaticResource OrderTitleStyle}"/> | |||
<Label | |||
Text="{Binding Order.Total, StringFormat='${0:N}', Converter={StaticResource ToUpperConverter}}" | |||
Style="{StaticResource OrderContentStyle}"/> | |||
</StackLayout> | |||
<StackLayout | |||
Grid.Column="1" | |||
Grid.Row="0" | |||
Margin="12"> | |||
<Label | |||
Text="DATE" | |||
Style="{StaticResource OrderTitleStyle}"/> | |||
<Label | |||
Text="{Binding Order.Date, Converter={StaticResource DatetimeConverter}}" | |||
Style="{StaticResource OrderContentStyle}"/> | |||
</StackLayout> | |||
<StackLayout | |||
Grid.Column="1" | |||
Grid.Row="1" | |||
Margin="12"> | |||
<Label | |||
Text="STATUS" | |||
Style="{StaticResource OrderTitleStyle}"/> | |||
<Label | |||
Text="{Binding Order.Status, Converter={StaticResource ToUpperConverter}}" | |||
Style="{StaticResource OrderContentStyle}"/> | |||
</StackLayout> | |||
</Grid> | |||
<!-- SHIPPING ADDRESS --> | |||
<Grid | |||
Grid.Row="1" | |||
Margin="12"> | |||
<Grid.RowDefinitions> | |||
<RowDefinition Height="Auto" /> | |||
<RowDefinition Height="*" /> | |||
</Grid.RowDefinitions> | |||
<Label | |||
Grid.Row="0" | |||
Text="SHIPPING ADDRESS" | |||
Style="{StaticResource ShippingAddressStyle}"/> | |||
<StackLayout | |||
Grid.Row="1"> | |||
<Label | |||
Text="120 E 87th Street" | |||
Style="{StaticResource AddressStyle}"/> | |||
<Label | |||
Text="Seattle, WA" | |||
Style="{StaticResource AddressStyle}"/> | |||
<Label | |||
Text="98122" | |||
Style="{StaticResource AddressStyle}"/> | |||
<Label | |||
Text="United States" | |||
Style="{StaticResource AddressStyle}"/> | |||
</StackLayout> | |||
</Grid> | |||
</Grid> | |||
</ScrollView> | |||
</ContentPage> |
@ -0,0 +1,12 @@ | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Views | |||
{ | |||
public partial class CartView : ContentPage | |||
{ | |||
public CartView() | |||
{ | |||
InitializeComponent(); | |||
} | |||
} | |||
} |
@ -0,0 +1,6 @@ | |||
<?xml version="1.0" encoding="utf-8" ?> | |||
<NavigationPage xmlns="http://xamarin.com/schemas/2014/forms" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | |||
x:Class="eShopOnContainers.Core.Views.CustomNavigationPage" | |||
BackgroundColor="Transparent"> | |||
</NavigationPage> |
@ -0,0 +1,17 @@ | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Views | |||
{ | |||
public partial class CustomNavigationPage : NavigationPage | |||
{ | |||
public CustomNavigationPage() : base() | |||
{ | |||
InitializeComponent(); | |||
} | |||
public CustomNavigationPage(Page root) : base(root) | |||
{ | |||
InitializeComponent(); | |||
} | |||
} | |||
} |
@ -0,0 +1,72 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<slideOverKit:SlideMenuView | |||
xmlns="http://xamarin.com/schemas/2014/forms" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | |||
xmlns:slideOverKit="clr-namespace:SlideOverKit" | |||
xmlns:controls="clr-namespace:eShopOnContainers.Core.Controls;assembly=eShopOnContainers.Core" | |||
x:Class="eShopOnContainers.Core.Views.FiltersView" | |||
MenuOrientations="TopToBottom" | |||
BackgroundColor="{StaticResource BackgroundColor}" | |||
HeightRequest="250" | |||
IsFullScreen="True"> | |||
<slideOverKit:SlideMenuView.Resources> | |||
<ResourceDictionary> | |||
<Style x:Key="FilterPickerStyle" | |||
TargetType="{x:Type controls:BindablePicker}"> | |||
<Setter Property="HeightRequest" | |||
Value="48" /> | |||
<Setter Property="BackgroundColor" | |||
Value="Transparent" /> | |||
<Setter Property="HorizontalOptions" | |||
Value="Fill" /> | |||
<Setter Property="VerticalOptions" | |||
Value="Fill" /> | |||
</Style> | |||
<Style x:Key="FilterButtonStyle" | |||
TargetType="{x:Type Button}"> | |||
<Setter Property="FontFamily" | |||
Value="{StaticResource MontserratRegular}" /> | |||
<Setter Property="TextColor" | |||
Value="{StaticResource WhiteColor}" /> | |||
<Setter Property="BackgroundColor" | |||
Value="{StaticResource LightGreenColor}" /> | |||
<Setter Property="HeightRequest" | |||
Value="48" /> | |||
<Setter Property="BorderRadius" | |||
Value="0" /> | |||
<Setter Property="BorderWidth" | |||
Value="0" /> | |||
<Setter Property="HorizontalOptions" | |||
Value="Fill" /> | |||
<Setter Property="VerticalOptions" | |||
Value="Fill" /> | |||
</Style> | |||
</ResourceDictionary> | |||
</slideOverKit:SlideMenuView.Resources> | |||
<Grid | |||
Padding="0" | |||
ColumnSpacing="0" | |||
RowSpacing="0" | |||
Margin="48, 24"> | |||
<Grid.RowDefinitions> | |||
<RowDefinition /> | |||
<RowDefinition /> | |||
<RowDefinition /> | |||
</Grid.RowDefinitions> | |||
<controls:BindablePicker | |||
Grid.Row="0" | |||
Title="BRAND" | |||
Style="{StaticResource FilterPickerStyle}"/> | |||
<controls:BindablePicker | |||
Grid.Row="1" | |||
Title="TYPE" | |||
Style="{StaticResource FilterPickerStyle}"/> | |||
<Button | |||
Grid.Row="2" | |||
Text="Apply" | |||
Style="{StaticResource FilterButtonStyle}"/> | |||
</Grid> | |||
</slideOverKit:SlideMenuView> |
@ -0,0 +1,12 @@ | |||
using SlideOverKit; | |||
namespace eShopOnContainers.Core.Views | |||
{ | |||
public partial class FiltersView : SlideMenuView | |||
{ | |||
public FiltersView() | |||
{ | |||
InitializeComponent(); | |||
} | |||
} | |||
} |
@ -0,0 +1,90 @@ | |||
<?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="eShopOnContainers.Core.Views.HomeView" | |||
xmlns:templates="clr-namespace:eShopOnContainers.Core.Views.Templates;assembly=eShopOnContainers.Core" | |||
xmlns:views="clr-namespace:eShopOnContainers.Core.Views;assembly=eShopOnContainers.Core" | |||
xmlns:animations="clr-namespace:eShopOnContainers.Core.Animations;assembly=eShopOnContainers.Core" | |||
xmlns:triggers="clr-namespace:eShopOnContainers.Core.Triggers;assembly=eShopOnContainers.Core" | |||
Title="Products"> | |||
<ContentPage.Resources> | |||
<ResourceDictionary> | |||
<Style x:Key="ProductsListStyle" | |||
TargetType="{x:Type ListView}"> | |||
<Setter Property="RowHeight" | |||
Value="400" /> | |||
<Setter Property="VerticalOptions" | |||
Value="Center" /> | |||
<Setter Property="Margin" | |||
Value="0" /> | |||
</Style> | |||
<Style x:Key="FilterLabelStyle" | |||
TargetType="{x:Type Label}"> | |||
<Setter Property="TextColor" | |||
Value="{StaticResource WhiteColor}" /> | |||
<Setter Property="HorizontalOptions" | |||
Value="Center" /> | |||
<Setter Property="VerticalOptions" | |||
Value="Center" /> | |||
</Style> | |||
<animations:StoryBoard | |||
x:Key="ProductsAnimation" | |||
Target="{x:Reference Products}"> | |||
<animations:FadeInAnimation | |||
Direction="Up" | |||
Duration="1500" | |||
Delay="250"/> | |||
</animations:StoryBoard> | |||
</ResourceDictionary> | |||
</ContentPage.Resources> | |||
<ContentPage.Triggers> | |||
<EventTrigger | |||
Event="Appearing"> | |||
<triggers:BeginAnimation | |||
Animation="{StaticResource ProductsAnimation}" /> | |||
</EventTrigger> | |||
</ContentPage.Triggers> | |||
<Grid | |||
ColumnSpacing="0" | |||
RowSpacing="0"> | |||
<Grid.RowDefinitions> | |||
<RowDefinition Height="60" /> | |||
<RowDefinition Height="*" /> | |||
</Grid.RowDefinitions> | |||
<!-- FILTERS --> | |||
<Grid | |||
BackgroundColor="{StaticResource LightGreenColor}"> | |||
<Label | |||
Text="FILTER" | |||
Style="{StaticResource FilterLabelStyle}"/> | |||
<Grid.GestureRecognizers> | |||
<TapGestureRecognizer | |||
Tapped="OnFilterChanged" | |||
NumberOfTapsRequired="1" /> | |||
</Grid.GestureRecognizers> | |||
</Grid> | |||
<!-- PRODUCTS --> | |||
<ListView | |||
x:Name="Products" | |||
Grid.Row="1" | |||
ItemsSource="{Binding Products}" | |||
SelectedItem="{Binding Product, Mode=TwoWay}" | |||
HasUnevenRows="True" | |||
SeparatorVisibility="None" | |||
CachingStrategy="RecycleElement" | |||
Style="{StaticResource ProductsListStyle}"> | |||
<ListView.ItemTemplate> | |||
<DataTemplate> | |||
<ViewCell> | |||
<templates:ProductTemplate /> | |||
</ViewCell> | |||
</DataTemplate> | |||
</ListView.ItemTemplate> | |||
</ListView> | |||
</Grid> | |||
</ContentPage> |
@ -0,0 +1,46 @@ | |||
using System; | |||
using SlideOverKit; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Views | |||
{ | |||
public partial class HomeView : ContentPage, IMenuContainerPage | |||
{ | |||
public HomeView() | |||
{ | |||
InitializeComponent(); | |||
SlideMenu = new FiltersView(); | |||
} | |||
public Action HideMenuAction | |||
{ | |||
get; | |||
set; | |||
} | |||
public Action ShowMenuAction | |||
{ | |||
get; | |||
set; | |||
} | |||
public SlideMenuView SlideMenu | |||
{ | |||
get; | |||
set; | |||
} | |||
private void OnFilterChanged(object sender, EventArgs e) | |||
{ | |||
if (SlideMenu.IsShown) | |||
{ | |||
HideMenuAction?.Invoke(); | |||
} | |||
else | |||
{ | |||
ShowMenuAction?.Invoke(); | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,163 @@ | |||
<?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="eShopOnContainers.Core.Views.LoginView" | |||
xmlns:animations="clr-namespace:eShopOnContainers.Core.Animations;assembly=eShopOnContainers.Core" | |||
xmlns:triggers="clr-namespace:eShopOnContainers.Core.Triggers;assembly=eShopOnContainers.Core" | |||
Title="eShop on Containers"> | |||
<ContentPage.Resources> | |||
<ResourceDictionary> | |||
<Style x:Key="TitleLabelStyle" | |||
TargetType="{x:Type Label}"> | |||
<Setter Property="FontFamily" | |||
Value="{StaticResource MontserratRegular}" /> | |||
<Setter Property="FontAttributes" | |||
Value="Bold" /> | |||
<Setter Property="FontSize" | |||
Value="{StaticResource MediumSize}" /> | |||
<Setter Property="HorizontalOptions" | |||
Value="Center" /> | |||
<Setter Property="Margin" | |||
Value="0, 12" /> | |||
</Style> | |||
<Style x:Key="HeaderLabelStyle" | |||
TargetType="{x:Type Label}"> | |||
<Setter Property="FontFamily" | |||
Value="{StaticResource MontserratRegular}" /> | |||
<Setter Property="FontSize" | |||
Value="{StaticResource LittleSize}" /> | |||
<Setter Property="TextColor" | |||
Value="{StaticResource GreenColor}" /> | |||
<Setter Property="HorizontalOptions" | |||
Value="Start" /> | |||
</Style> | |||
<Style x:Key="LoginButtonStyle" | |||
TargetType="{x:Type Label}"> | |||
<Setter Property="FontFamily" | |||
Value="{StaticResource MontserratRegular}" /> | |||
<Setter Property="TextColor" | |||
Value="{StaticResource WhiteColor}" /> | |||
<Setter Property="HorizontalOptions" | |||
Value="Center" /> | |||
<Setter Property="VerticalOptions" | |||
Value="Center" /> | |||
</Style> | |||
<animations:StoryBoard | |||
x:Key="LoginAnimation" | |||
Target="{x:Reference LoginPanel}"> | |||
<animations:FadeInAnimation | |||
Direction="Up" | |||
Duration="1500" /> | |||
</animations:StoryBoard> | |||
</ResourceDictionary> | |||
</ContentPage.Resources> | |||
<ContentPage.Triggers> | |||
<EventTrigger | |||
Event="Appearing"> | |||
<triggers:BeginAnimation | |||
Animation="{StaticResource LoginAnimation}" /> | |||
</EventTrigger> | |||
</ContentPage.Triggers> | |||
<Grid | |||
BackgroundColor="{StaticResource BackgroundColor}"> | |||
<Grid | |||
x:Name="LoginPanel" | |||
Padding="0" | |||
ColumnSpacing="0" | |||
RowSpacing="0"> | |||
<Grid.RowDefinitions> | |||
<RowDefinition Height="Auto" /> | |||
<RowDefinition Height="Auto" /> | |||
<RowDefinition Height="*" /> | |||
<RowDefinition Height="60" /> | |||
</Grid.RowDefinitions> | |||
<!-- LOGIN / REGISTER --> | |||
<Grid | |||
Grid.Row="0" | |||
Margin="48, 24"> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition /> | |||
<ColumnDefinition /> | |||
</Grid.ColumnDefinitions> | |||
<StackLayout | |||
Grid.Column="0" | |||
Orientation="Horizontal" | |||
HorizontalOptions="Center"> | |||
<Label | |||
Text="[" | |||
TextColor="{StaticResource LightGreenColor}"/> | |||
<Label | |||
Text="LOGIN" | |||
FontAttributes="Bold"/> | |||
<Label | |||
Text="]" | |||
TextColor="{StaticResource LightGreenColor}"/> | |||
</StackLayout> | |||
<Grid | |||
Grid.Column="1" | |||
HorizontalOptions="Center"> | |||
<Label | |||
Text="REGISTER" | |||
TextColor="Gray"/> | |||
</Grid> | |||
</Grid> | |||
<!-- INFO --> | |||
<Label | |||
Grid.Row="1" | |||
Text="ARE YOU REGISTERED?" | |||
Style="{StaticResource TitleLabelStyle}"/> | |||
<!-- LOGIN FORM --> | |||
<StackLayout | |||
Grid.Row="2" | |||
Margin="24"> | |||
<Label | |||
Text="User name or email" | |||
Style="{StaticResource HeaderLabelStyle}"/> | |||
<Entry | |||
Text="{Binding UserName.Value, Mode=TwoWay}"/> | |||
<Label | |||
Text="Password" | |||
Style="{StaticResource HeaderLabelStyle}"/> | |||
<Entry | |||
IsPassword="True" | |||
Text="{Binding Password.Value, Mode=TwoWay}" /> | |||
</StackLayout> | |||
<!-- LOGIN BUTTON --> | |||
<Grid | |||
BackgroundColor="{StaticResource LightGreenColor}" | |||
Grid.Row="3" | |||
Padding="0" | |||
ColumnSpacing="0" | |||
RowSpacing="0"> | |||
<Label | |||
Text="[ LOGIN ]" | |||
Style="{StaticResource LoginButtonStyle}"/> | |||
<Grid.GestureRecognizers> | |||
<TapGestureRecognizer | |||
Command="{Binding SignInCommand}" | |||
NumberOfTapsRequired="1" /> | |||
</Grid.GestureRecognizers> | |||
</Grid> | |||
</Grid> | |||
<!-- INDICATOR --> | |||
<ActivityIndicator | |||
Color="{StaticResource AccentColor}" | |||
IsRunning="{Binding IsBusy}" | |||
IsVisible="{Binding IsBusy}" | |||
VerticalOptions="Center" | |||
HorizontalOptions="Center"> | |||
<ActivityIndicator.WidthRequest> | |||
<OnPlatform | |||
x:TypeArguments="x:Double" | |||
iOS="100" | |||
Android="100" | |||
WinPhone="400" /> | |||
</ActivityIndicator.WidthRequest> | |||
</ActivityIndicator> | |||
</Grid> | |||
</ContentPage> |
@ -0,0 +1,12 @@ | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Views | |||
{ | |||
public partial class LoginView : ContentPage | |||
{ | |||
public LoginView() | |||
{ | |||
InitializeComponent(); | |||
} | |||
} | |||
} |
@ -0,0 +1,42 @@ | |||
<?xml version="1.0" encoding="utf-8" ?> | |||
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | |||
x:Class="eShopOnContainers.Core.Views.MainView" | |||
xmlns:views="clr-namespace:eShopOnContainers.Core.Views;assembly=eShopOnContainers.Core" | |||
xmlns:controls="clr-namespace:eShopOnContainers.Core.Controls;assembly=eShopOnContainers.Core" | |||
BarBackgroundColor="{StaticResource DarkGreenColor}" | |||
BackgroundColor="{StaticResource BackgroundColor}" | |||
Title="eShop on Containers"> | |||
<views:HomeView | |||
x:Name="HomeView"> | |||
<views:HomeView.Icon> | |||
<OnPlatform | |||
x:TypeArguments="FileImageSource" | |||
Android="menu_filter" | |||
iOS="menu_filter" | |||
WinPhone="Assets\menu_filter.png"/> | |||
</views:HomeView.Icon> | |||
</views:HomeView> | |||
<views:ProfileView | |||
x:Name="ProfileView"> | |||
<views:HomeView.Icon> | |||
<OnPlatform | |||
x:TypeArguments="FileImageSource" | |||
Android="menu_profile" | |||
iOS="menu_profile" | |||
WinPhone="Assets\menu_profile.png"/> | |||
</views:HomeView.Icon> | |||
</views:ProfileView> | |||
<views:CartView | |||
x:Name="CartView" | |||
controls:CustomTabbedPage.BadgeText="{Binding BadgeCount}" | |||
controls:CustomTabbedPage.BadgeColor="{StaticResource LightGreenColor}"> | |||
<views:HomeView.Icon> | |||
<OnPlatform | |||
x:TypeArguments="FileImageSource" | |||
Android="menu_cart" | |||
iOS="menu_cart" | |||
WinPhone="Assets\menu_cart.png"/> | |||
</views:HomeView.Icon> | |||
</views:CartView> | |||
</TabbedPage> |
@ -0,0 +1,31 @@ | |||
using eShopOnContainers.Core.ViewModels; | |||
using eShopOnContainers.ViewModels.Base; | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Views | |||
{ | |||
public partial class MainView : TabbedPage | |||
{ | |||
public MainView() | |||
{ | |||
InitializeComponent(); | |||
} | |||
protected override async void OnAppearing() | |||
{ | |||
base.OnAppearing(); | |||
var homeViewModel = ViewModelLocator.Instance.Resolve<ProductsViewModel>(); | |||
await homeViewModel.InitializeAsync(null); | |||
HomeView.BindingContext = homeViewModel; | |||
var profileViewModel = ViewModelLocator.Instance.Resolve<ProfileViewModel>(); | |||
await profileViewModel.InitializeAsync(null); | |||
ProfileView.BindingContext = profileViewModel; | |||
var cartViewModel = ViewModelLocator.Instance.Resolve<CartViewModel>(); | |||
await cartViewModel.InitializeAsync(null); | |||
CartView.BindingContext = cartViewModel; | |||
} | |||
} | |||
} |
@ -0,0 +1,6 @@ | |||
<?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="eShopOnContainers.Core.Views.OrderDetailView"> | |||
</ContentPage> |
@ -0,0 +1,12 @@ | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Views | |||
{ | |||
public partial class OrderDetailView : ContentPage | |||
{ | |||
public OrderDetailView() | |||
{ | |||
InitializeComponent(); | |||
} | |||
} | |||
} |
@ -0,0 +1,6 @@ | |||
<?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="eShopOnContainers.Core.Views.OrdersView"> | |||
</ContentPage> |
@ -0,0 +1,12 @@ | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Views | |||
{ | |||
public partial class OrdersView : ContentPage | |||
{ | |||
public OrdersView() | |||
{ | |||
InitializeComponent(); | |||
} | |||
} | |||
} |
@ -0,0 +1,96 @@ | |||
<?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="eShopOnContainers.Core.Views.ProfileView" | |||
xmlns:views="clr-namespace:eShopOnContainers.Core.Views;assembly=eShopOnContainers.Core" | |||
xmlns:templates="clr-namespace:eShopOnContainers.Core.Views.Templates;assembly=eShopOnContainers.Core" | |||
Title="My profile"> | |||
<ContentPage.Resources> | |||
<ResourceDictionary> | |||
<Style x:Key="LogoutLabelStyle" | |||
TargetType="{x:Type Label}"> | |||
<Setter Property="HorizontalOptions" | |||
Value="Center" /> | |||
<Setter Property="VerticalOptions" | |||
Value="Center" /> | |||
</Style> | |||
<Style x:Key="LoginButtonStyle" | |||
TargetType="{x:Type Label}"> | |||
<Setter Property="FontFamily" | |||
Value="{StaticResource MontserratRegular}" /> | |||
<Setter Property="TextColor" | |||
Value="{StaticResource WhiteColor}" /> | |||
<Setter Property="HorizontalOptions" | |||
Value="Center" /> | |||
<Setter Property="VerticalOptions" | |||
Value="Center" /> | |||
</Style> | |||
<Style x:Key="MyOrdersLabelStyle" | |||
TargetType="{x:Type Label}"> | |||
<Setter Property="FontFamily" | |||
Value="{StaticResource MontserratRegular}" /> | |||
<Setter Property="FontSize" | |||
Value="{StaticResource MediumSize}" /> | |||
<Setter Property="HorizontalOptions" | |||
Value="Center" /> | |||
<Setter Property="VerticalOptions" | |||
Value="Center" /> | |||
<Setter Property="Margin" | |||
Value="0, 12" /> | |||
</Style> | |||
</ResourceDictionary> | |||
</ContentPage.Resources> | |||
<Grid | |||
Padding="0" | |||
ColumnSpacing="0" | |||
RowSpacing="0" | |||
BackgroundColor="{StaticResource BackgroundColor}"> | |||
<Grid.RowDefinitions> | |||
<RowDefinition Height="60" /> | |||
<RowDefinition Height="*" /> | |||
</Grid.RowDefinitions> | |||
<!-- LOG OUT BUTTON --> | |||
<Grid | |||
Grid.Row="0" | |||
BackgroundColor="{StaticResource GrayColor}"> | |||
<Label | |||
Text="LOG OUT" | |||
Style="{StaticResource LogoutLabelStyle}"/> | |||
<Grid.GestureRecognizers> | |||
<TapGestureRecognizer | |||
Command="{Binding LogoutCommand}" | |||
NumberOfTapsRequired="1" /> | |||
</Grid.GestureRecognizers> | |||
</Grid> | |||
<!-- ORDERS --> | |||
<Grid | |||
Grid.Row="1"> | |||
<Grid.RowDefinitions> | |||
<RowDefinition Height="Auto" /> | |||
<RowDefinition Height="*" /> | |||
</Grid.RowDefinitions> | |||
<Label | |||
Grid.Row="0" | |||
Text="MY ORDERS" | |||
Style="{StaticResource MyOrdersLabelStyle}"/> | |||
<ListView | |||
Grid.Row="1" | |||
ItemsSource="{Binding Orders}" | |||
HasUnevenRows="True" | |||
SeparatorVisibility="None" | |||
CachingStrategy="RecycleElement"> | |||
<ListView.ItemTemplate> | |||
<DataTemplate> | |||
<ViewCell> | |||
<templates:OrderTemplate /> | |||
</ViewCell> | |||
</DataTemplate> | |||
</ListView.ItemTemplate> | |||
</ListView> | |||
</Grid> | |||
</Grid> | |||
</ContentPage> |
@ -0,0 +1,12 @@ | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Views | |||
{ | |||
public partial class ProfileView : ContentPage | |||
{ | |||
public ProfileView() | |||
{ | |||
InitializeComponent(); | |||
} | |||
} | |||
} |
@ -0,0 +1,91 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<ContentView | |||
xmlns="http://xamarin.com/schemas/2014/forms" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | |||
x:Class="eShopOnContainers.Core.Views.Templates.OrderTemplate"> | |||
<ContentView.Resources> | |||
<ResourceDictionary> | |||
<Style x:Key="OrderTitleStyle" | |||
TargetType="{x:Type Label}"> | |||
<Setter Property="FontFamily" | |||
Value="{StaticResource MontserratRegular}" /> | |||
<Setter Property="FontSize" | |||
Value="{StaticResource MediumSize}" /> | |||
<Setter Property="TextColor" | |||
Value="Gray" /> | |||
</Style> | |||
<Style x:Key="OrderContentStyle" | |||
TargetType="{x:Type Label}" | |||
BasedOn="{StaticResource OrderTitleStyle}"> | |||
<Setter Property="TextColor" | |||
Value="Black" /> | |||
</Style> | |||
</ResourceDictionary> | |||
</ContentView.Resources> | |||
<ContentView.Content> | |||
<Grid | |||
BackgroundColor="{StaticResource BackgroundColor}"> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition /> | |||
<ColumnDefinition /> | |||
</Grid.ColumnDefinitions> | |||
<Grid.RowDefinitions> | |||
<RowDefinition /> | |||
<RowDefinition /> | |||
<RowDefinition Height="1" /> | |||
</Grid.RowDefinitions> | |||
<StackLayout | |||
Grid.Column="0" | |||
Grid.Row="0" | |||
Margin="12"> | |||
<Label | |||
Text="ORDER NUMBER" | |||
Style="{StaticResource OrderTitleStyle}"/> | |||
<Label | |||
Text="{Binding OrderNumber, Converter={StaticResource ToUpperConverter}}" | |||
Style="{StaticResource OrderContentStyle}"/> | |||
</StackLayout> | |||
<StackLayout | |||
Grid.Column="0" | |||
Grid.Row="1" | |||
Margin="12"> | |||
<Label | |||
Text="TOTAL" | |||
Style="{StaticResource OrderTitleStyle}"/> | |||
<Label | |||
Text="{Binding Total, StringFormat='${0:N}', Converter={StaticResource ToUpperConverter}}" | |||
Style="{StaticResource OrderContentStyle}"/> | |||
</StackLayout> | |||
<StackLayout | |||
Grid.Column="1" | |||
Grid.Row="0" | |||
Margin="12"> | |||
<Label | |||
Text="DATE" | |||
Style="{StaticResource OrderTitleStyle}"/> | |||
<Label | |||
Text="{Binding Date, Converter={StaticResource DatetimeConverter}}" | |||
Style="{StaticResource OrderContentStyle}"/> | |||
</StackLayout> | |||
<StackLayout | |||
Grid.Column="1" | |||
Grid.Row="1" | |||
Margin="12"> | |||
<Label | |||
Text="STATUS" | |||
Style="{StaticResource OrderTitleStyle}"/> | |||
<Label | |||
Text="{Binding Status, Converter={StaticResource ToUpperConverter}}" | |||
Style="{StaticResource OrderContentStyle}"/> | |||
</StackLayout> | |||
<Grid | |||
Grid.Column="0" | |||
Grid.ColumnSpan="2" | |||
Grid.Row="2" | |||
BackgroundColor="Gray"/> | |||
</Grid> | |||
</ContentView.Content> | |||
</ContentView> |
@ -0,0 +1,12 @@ | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Views.Templates | |||
{ | |||
public partial class OrderTemplate : ContentView | |||
{ | |||
public OrderTemplate() | |||
{ | |||
InitializeComponent(); | |||
} | |||
} | |||
} |
@ -0,0 +1,111 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<ContentView | |||
xmlns="http://xamarin.com/schemas/2014/forms" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | |||
x:Class="eShopOnContainers.Core.Views.Templates.ProductTemplate"> | |||
<ContentView.Resources> | |||
<ResourceDictionary> | |||
<Style x:Key="ProductNameStyle" | |||
TargetType="{x:Type Label}"> | |||
<Setter Property="FontFamily" | |||
Value="{StaticResource MontserratRegular}" /> | |||
<Setter Property="FontSize" | |||
Value="{StaticResource LargeSize}" /> | |||
<Setter Property="HorizontalOptions" | |||
Value="Center" /> | |||
<Setter Property="Margin" | |||
Value="0, 12, 0, 6" /> | |||
</Style> | |||
<Style x:Key="ProductPriceStyle" | |||
TargetType="{x:Type Label}"> | |||
<Setter Property="FontAttributes" | |||
Value="Bold" /> | |||
<Setter Property="FontFamily" | |||
Value="{StaticResource MontserratRegular}" /> | |||
<Setter Property="FontSize" | |||
Value="{StaticResource BigSize}" /> | |||
<Setter Property="TextColor" | |||
Value="{StaticResource BlackColor}" /> | |||
<Setter Property="HorizontalOptions" | |||
Value="Center" /> | |||
<Setter Property="Margin" | |||
Value="0, 6, 0, 12" /> | |||
</Style> | |||
<Style x:Key="AddButtonStyle" | |||
TargetType="{x:Type Grid}"> | |||
<Setter Property="HeightRequest" | |||
Value="42" /> | |||
<Setter Property="WidthRequest" | |||
Value="42" /> | |||
<Setter Property="HorizontalOptions" | |||
Value="Center" /> | |||
<Setter Property="VerticalOptions" | |||
Value="End" /> | |||
<Setter Property="Margin" | |||
Value="0,0,0,24" /> | |||
</Style> | |||
<Style x:Key="AddImageStyle" | |||
TargetType="{x:Type Image}"> | |||
<Setter Property="HeightRequest" | |||
Value="24" /> | |||
<Setter Property="WidthRequest" | |||
Value="24" /> | |||
</Style> | |||
</ResourceDictionary> | |||
</ContentView.Resources> | |||
<ContentView.Content> | |||
<Grid | |||
BackgroundColor="{StaticResource BackgroundColor}" | |||
Padding="0" | |||
Margin="0"> | |||
<Grid.RowDefinitions> | |||
<RowDefinition Height="250" /> | |||
<RowDefinition Height="Auto" /> | |||
<RowDefinition Height="Auto" /> | |||
</Grid.RowDefinitions> | |||
<Image | |||
Grid.Row="0" | |||
Source="{Binding Image}" | |||
Aspect="AspectFill"/> | |||
<Grid | |||
Grid.Row="0" | |||
Grid.RowSpan="2" | |||
Style="{StaticResource AddButtonStyle}"> | |||
<BoxView | |||
BackgroundColor="{StaticResource LightGreenColor}" | |||
StyleClass="Circle"/> | |||
<Image | |||
Aspect="AspectFit" | |||
Style="{StaticResource AddImageStyle}"> | |||
<Image.Margin> | |||
<OnPlatform | |||
x:TypeArguments="Thickness" | |||
Android="6, 12, 12, 12" | |||
iOS="6, 12, 12, 12" | |||
WinPhone="8, 12, 12, 12"/> | |||
</Image.Margin> | |||
<Image.Source> | |||
<OnPlatform | |||
x:TypeArguments="ImageSource" | |||
Android="product_add" | |||
iOS="product_add" | |||
WinPhone="Assets\product_add.png"/> | |||
</Image.Source> | |||
</Image> | |||
</Grid> | |||
<Label | |||
Grid.Row="1" | |||
Text="{Binding Name, Converter={StaticResource ToUpperConverter}}" | |||
Style="{StaticResource ProductNameStyle}"/> | |||
<Label | |||
Grid.Row="2" | |||
Text="{Binding Price, StringFormat='${0:N}'}" | |||
Style="{StaticResource ProductPriceStyle}"/> | |||
</Grid> | |||
</ContentView.Content> | |||
</ContentView> |
@ -0,0 +1,12 @@ | |||
using Xamarin.Forms; | |||
namespace eShopOnContainers.Core.Views.Templates | |||
{ | |||
public partial class ProductTemplate : ContentView | |||
{ | |||
public ProductTemplate() | |||
{ | |||
InitializeComponent(); | |||
} | |||
} | |||
} |
@ -0,0 +1,11 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<configuration> | |||
<runtime> | |||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> | |||
<dependentAssembly> | |||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" /> | |||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" /> | |||
</dependentAssembly> | |||
</assemblyBinding> | |||
</runtime> | |||
</configuration> |
@ -0,0 +1,258 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> | |||
<PropertyGroup> | |||
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion> | |||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | |||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | |||
<ProjectGuid>{65116D1C-145B-4693-ABDA-F0FB6F425191}</ProjectGuid> | |||
<OutputType>Library</OutputType> | |||
<AppDesignerFolder>Properties</AppDesignerFolder> | |||
<RootNamespace>eShopOnContainers.Core</RootNamespace> | |||
<AssemblyName>eShopOnContainers.Core</AssemblyName> | |||
<FileAlignment>512</FileAlignment> | |||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> | |||
<TargetFrameworkProfile>Profile259</TargetFrameworkProfile> | |||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | |||
<NuGetPackageImportStamp> | |||
</NuGetPackageImportStamp> | |||
</PropertyGroup> | |||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | |||
<DebugSymbols>true</DebugSymbols> | |||
<DebugType>full</DebugType> | |||
<Optimize>false</Optimize> | |||
<OutputPath>bin\Debug\</OutputPath> | |||
<DefineConstants>DEBUG;TRACE</DefineConstants> | |||
<ErrorReport>prompt</ErrorReport> | |||
<WarningLevel>4</WarningLevel> | |||
</PropertyGroup> | |||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | |||
<DebugType>pdbonly</DebugType> | |||
<Optimize>true</Optimize> | |||
<OutputPath>bin\Release\</OutputPath> | |||
<DefineConstants>TRACE</DefineConstants> | |||
<ErrorReport>prompt</ErrorReport> | |||
<WarningLevel>4</WarningLevel> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<Compile Include="Animations\Base\AnimationBase.cs" /> | |||
<Compile Include="Animations\Base\EasingType.cs" /> | |||
<Compile Include="Animations\FadeToAnimation.cs" /> | |||
<Compile Include="Animations\StoryBoard.cs" /> | |||
<Compile Include="App.xaml.cs"> | |||
<DependentUpon>App.xaml</DependentUpon> | |||
</Compile> | |||
<Compile Include="Controls\BindablePicker.cs" /> | |||
<Compile Include="Controls\CustomTabbedPage.cs" /> | |||
<Compile Include="Converters\DatetimeConverter.cs" /> | |||
<Compile Include="Converters\ToUpperConverter.cs" /> | |||
<Compile Include="Effects\LineColorEffect.cs" /> | |||
<Compile Include="Extensions\AnimationExtension.cs" /> | |||
<Compile Include="Helpers\EasingHelper.cs" /> | |||
<Compile Include="Models\Orders\Order.cs" /> | |||
<Compile Include="Models\Orders\OrderStatus.cs" /> | |||
<Compile Include="Models\Products\Product.cs" /> | |||
<Compile Include="Properties\AssemblyInfo.cs" /> | |||
<Compile Include="Services\Dialog\DialogService.cs" /> | |||
<Compile Include="Services\Dialog\IDialogService.cs" /> | |||
<Compile Include="Services\Navigation\INavigationService.cs" /> | |||
<Compile Include="Services\Navigation\NavigationService.cs" /> | |||
<Compile Include="Services\Orders\FakeOrdersService.cs" /> | |||
<Compile Include="Services\Orders\IOrdersService.cs" /> | |||
<Compile Include="Services\Products\FakeProductsService.cs" /> | |||
<Compile Include="Services\Products\IProductsService.cs" /> | |||
<Compile Include="Triggers\BeginAnimation.cs" /> | |||
<Compile Include="Validations\IsNotNullOrEmptyRule.cs" /> | |||
<Compile Include="Validations\IValidationRule.cs" /> | |||
<Compile Include="Validations\IValidity.cs" /> | |||
<Compile Include="Validations\ValidatableObject.cs" /> | |||
<Compile Include="ViewModels\Base\ExtendedBindableObject.cs" /> | |||
<Compile Include="ViewModels\Base\MessengerKeys.cs" /> | |||
<Compile Include="ViewModels\Base\ViewModelBase.cs" /> | |||
<Compile Include="ViewModels\Base\ViewModelLocator.cs" /> | |||
<Compile Include="ViewModels\CartViewModel.cs" /> | |||
<Compile Include="ViewModels\ProductsViewModel.cs" /> | |||
<Compile Include="ViewModels\LoginViewModel.cs" /> | |||
<Compile Include="ViewModels\MainViewModel.cs" /> | |||
<Compile Include="ViewModels\OrderDetailViewModel.cs" /> | |||
<Compile Include="ViewModels\OrdersViewModel.cs" /> | |||
<Compile Include="ViewModels\ProfileViewModel.cs" /> | |||
<Compile Include="Views\CartView.xaml.cs"> | |||
<DependentUpon>CartView.xaml</DependentUpon> | |||
</Compile> | |||
<Compile Include="Views\CustomNavigationPage.xaml.cs"> | |||
<DependentUpon>CustomNavigationPage.xaml</DependentUpon> | |||
</Compile> | |||
<Compile Include="Views\FiltersView.xaml.cs"> | |||
<DependentUpon>FiltersView.xaml</DependentUpon> | |||
</Compile> | |||
<Compile Include="Views\HomeView.xaml.cs"> | |||
<DependentUpon>HomeView.xaml</DependentUpon> | |||
</Compile> | |||
<Compile Include="Views\LoginView.xaml.cs"> | |||
<DependentUpon>LoginView.xaml</DependentUpon> | |||
</Compile> | |||
<Compile Include="Views\MainView.xaml.cs"> | |||
<DependentUpon>MainView.xaml</DependentUpon> | |||
</Compile> | |||
<Compile Include="Views\OrderDetailView.xaml.cs"> | |||
<DependentUpon>OrderDetailView.xaml</DependentUpon> | |||
</Compile> | |||
<Compile Include="Views\OrdersView.xaml.cs"> | |||
<DependentUpon>OrdersView.xaml</DependentUpon> | |||
</Compile> | |||
<Compile Include="Views\ProfileView.xaml.cs"> | |||
<DependentUpon>ProfileView.xaml</DependentUpon> | |||
</Compile> | |||
<Compile Include="Views\Templates\OrderTemplate.xaml.cs"> | |||
<DependentUpon>OrderTemplate.xaml</DependentUpon> | |||
</Compile> | |||
<Compile Include="Views\Templates\ProductTemplate.xaml.cs"> | |||
<DependentUpon>ProductTemplate.xaml</DependentUpon> | |||
</Compile> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<EmbeddedResource Include="App.xaml"> | |||
<SubType>Designer</SubType> | |||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> | |||
</EmbeddedResource> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<EmbeddedResource Include="Views\FiltersView.xaml"> | |||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> | |||
<SubType>Designer</SubType> | |||
</EmbeddedResource> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Reference Include="Acr.UserDialogs, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\Acr.UserDialogs.6.3.1\lib\portable-win+net45+wp8+win8+wpa81\Acr.UserDialogs.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="Acr.UserDialogs.Interface, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\Acr.UserDialogs.6.3.1\lib\portable-win+net45+wp8+win8+wpa81\Acr.UserDialogs.Interface.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="Microsoft.Practices.ServiceLocation, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="Microsoft.Practices.Unity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\Unity.4.0.1\lib\portable-net45+wp80+win8+wpa81+MonoAndroid10+MonoTouch10\Microsoft.Practices.Unity.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="ModernHttpClient, Version=2.4.2.0, Culture=neutral, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\modernhttpclient.2.4.2\lib\Portable-Net45+WinRT45+WP8+WPA81\ModernHttpClient.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\Newtonsoft.Json.8.0.3\lib\portable-net40+sl5+wp80+win8+wpa81\Newtonsoft.Json.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="SlideOverKit, Version=1.0.6135.18790, Culture=neutral, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\SlideOverKit.2.1.4\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\SlideOverKit.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="Splat, Version=1.6.2.0, Culture=neutral, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\Xamarin.Forms.2.3.2.127\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Core.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="Xamarin.Forms.Pages, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\Xamarin.Forms.Pages.2.3.0.38-pre2\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Pages.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="Xamarin.Forms.Platform, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\Xamarin.Forms.2.3.2.127\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Platform.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="Xamarin.Forms.Theme.Base, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\Xamarin.Forms.Theme.Base.1.0.0.43-pre1\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Theme.Base.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="Xamarin.Forms.Theme.Light, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\Xamarin.Forms.Theme.Light.1.0.0.43-pre1\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Theme.Light.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
<Reference Include="Xamarin.Forms.Xaml, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | |||
<HintPath>..\..\packages\Xamarin.Forms.2.3.2.127\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.Xaml.dll</HintPath> | |||
<Private>True</Private> | |||
</Reference> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<None Include="app.config" /> | |||
<None Include="packages.config" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<EmbeddedResource Include="Views\HomeView.xaml"> | |||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> | |||
<SubType>Designer</SubType> | |||
</EmbeddedResource> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<EmbeddedResource Include="Views\CartView.xaml"> | |||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> | |||
<SubType>Designer</SubType> | |||
</EmbeddedResource> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<EmbeddedResource Include="Views\LoginView.xaml"> | |||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> | |||
<SubType>Designer</SubType> | |||
</EmbeddedResource> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<EmbeddedResource Include="Views\ProfileView.xaml"> | |||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> | |||
<SubType>Designer</SubType> | |||
</EmbeddedResource> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<EmbeddedResource Include="Views\OrderDetailView.xaml"> | |||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> | |||
<SubType>Designer</SubType> | |||
</EmbeddedResource> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<EmbeddedResource Include="Views\OrdersView.xaml"> | |||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> | |||
<SubType>Designer</SubType> | |||
</EmbeddedResource> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<EmbeddedResource Include="Views\CustomNavigationPage.xaml"> | |||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> | |||
<SubType>Designer</SubType> | |||
</EmbeddedResource> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<EmbeddedResource Include="Views\Templates\ProductTemplate.xaml"> | |||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> | |||
<SubType>Designer</SubType> | |||
</EmbeddedResource> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<EmbeddedResource Include="Views\MainView.xaml"> | |||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> | |||
<SubType>Designer</SubType> | |||
</EmbeddedResource> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<EmbeddedResource Include="Views\Templates\OrderTemplate.xaml"> | |||
<Generator>MSBuild:UpdateDesignTimeXaml</Generator> | |||
<SubType>Designer</SubType> | |||
</EmbeddedResource> | |||
</ItemGroup> | |||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" /> | |||
<Import Project="..\..\packages\Xamarin.Forms.2.3.2.127\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.targets" Condition="Exists('..\..\packages\Xamarin.Forms.2.3.2.127\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.targets')" /> | |||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> | |||
<PropertyGroup> | |||
<ErrorText>Este proyecto hace referencia a los paquetes NuGet que faltan en este equipo. Use la restauración de paquetes NuGet para descargarlos. Para obtener más información, consulte http://go.microsoft.com/fwlink/?LinkID=322105. El archivo que falta es {0}.</ErrorText> | |||
</PropertyGroup> | |||
<Error Condition="!Exists('..\..\packages\Xamarin.Forms.2.3.2.127\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Forms.2.3.2.127\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+MonoTouch10+Xamarin.iOS10\Xamarin.Forms.targets'))" /> | |||
<Error Condition="!Exists('..\..\packages\StyleCop.MSBuild.5.0.0-alpha01\build\StyleCop.MSBuild.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\StyleCop.MSBuild.5.0.0-alpha01\build\StyleCop.MSBuild.targets'))" /> | |||
</Target> | |||
<Import Project="..\..\packages\StyleCop.MSBuild.5.0.0-alpha01\build\StyleCop.MSBuild.targets" Condition="Exists('..\..\packages\StyleCop.MSBuild.5.0.0-alpha01\build\StyleCop.MSBuild.targets')" /> | |||
</Project> |
@ -0,0 +1,15 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<packages> | |||
<package id="Acr.UserDialogs" version="6.3.1" targetFramework="portable45-net45+win8+wp8+wpa81" /> | |||
<package id="CommonServiceLocator" version="1.3" targetFramework="portable45-net45+win8+wp8+wpa81" /> | |||
<package id="modernhttpclient" version="2.4.2" targetFramework="portable45-net45+win8+wp8+wpa81" /> | |||
<package id="Newtonsoft.Json" version="8.0.3" targetFramework="portable45-net45+win8+wp8+wpa81" /> | |||
<package id="SlideOverKit" version="2.1.4" targetFramework="portable45-net45+win8+wp8+wpa81" /> | |||
<package id="Splat" version="1.6.2" targetFramework="portable45-net45+win8+wp8+wpa81" /> | |||
<package id="StyleCop.MSBuild" version="5.0.0-alpha01" targetFramework="portable45-net45+win8+wp8+wpa81" developmentDependency="true" /> | |||
<package id="Unity" version="4.0.1" targetFramework="portable45-net45+win8+wp8+wpa81" /> | |||
<package id="Xamarin.Forms" version="2.3.2.127" targetFramework="portable45-net45+win8+wp8+wpa81" /> | |||
<package id="Xamarin.Forms.Pages" version="2.3.0.38-pre2" targetFramework="portable45-net45+win8+wp8+wpa81" /> | |||
<package id="Xamarin.Forms.Theme.Base" version="1.0.0.43-pre1" targetFramework="portable45-net45+win8+wp8+wpa81" /> | |||
<package id="Xamarin.Forms.Theme.Light" version="1.0.0.43-pre1" targetFramework="portable45-net45+win8+wp8+wpa81" /> | |||
</packages> |
@ -0,0 +1,37 @@ | |||
using Android.App; | |||
using Android.OS; | |||
using Android.Content.PM; | |||
using Android.Views; | |||
namespace eShopOnContainers.Droid.Activities | |||
{ | |||
[Activity( | |||
Label = "eShopOnContainers", | |||
Icon = "@drawable/icon", | |||
Theme = "@style/MainTheme", | |||
MainLauncher = true, | |||
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)] | |||
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity | |||
{ | |||
protected override void OnCreate(Bundle bundle) | |||
{ | |||
TabLayoutResource = Resource.Layout.Tabbar; | |||
ToolbarResource = Resource.Layout.Toolbar; | |||
base.OnCreate(bundle); | |||
global::Xamarin.Forms.Forms.Init(this, bundle); | |||
LoadApplication(new App()); | |||
var x = typeof(Xamarin.Forms.Themes.LightThemeResources); | |||
x = typeof(Xamarin.Forms.Themes.Android.UnderlineEffect); | |||
Window window = this.Window; | |||
window.ClearFlags(WindowManagerFlags.TranslucentStatus); | |||
window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds); | |||
window.SetStatusBarColor(Android.Graphics.Color.Rgb(0, 166, 156)); | |||
} | |||
} | |||
} | |||
@ -0,0 +1,31 @@ | |||
using Android.App; | |||
using Android.Content; | |||
using Android.Content.PM; | |||
using Android.OS; | |||
using Android.Support.V7.App; | |||
namespace eShopOnContainers.Droid.Activities | |||
{ | |||
[Activity( | |||
Label = "eShopOnContainers", | |||
Icon = "@drawable/icon", | |||
Theme = "@style/Theme.Splash", | |||
MainLauncher = true, | |||
NoHistory = true, | |||
ScreenOrientation = ScreenOrientation.Portrait)] | |||
public class SplashActivity : AppCompatActivity | |||
{ | |||
protected override void OnCreate(Bundle bundle) | |||
{ | |||
base.OnCreate(bundle); | |||
InvokeMainActivity(); | |||
} | |||
private void InvokeMainActivity() | |||
{ | |||
var mainActivityIntent = new Intent(this, typeof(MainActivity)); | |||
StartActivity(mainActivityIntent); | |||
} | |||
} | |||
} |
@ -0,0 +1,19 @@ | |||
Any raw assets you want to be deployed with your application can be placed in | |||
this directory (and child directories) and given a Build Action of "AndroidAsset". | |||
These files will be deployed with you package and will be accessible using Android's | |||
AssetManager, like this: | |||
public class ReadAsset : Activity | |||
{ | |||
protected override void OnCreate (Bundle bundle) | |||
{ | |||
base.OnCreate (bundle); | |||
InputStream input = Assets.Open ("my_asset.txt"); | |||
} | |||
} | |||
Additionally, some Android functions will automatically load asset files: | |||
Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); |
@ -0,0 +1,58 @@ | |||
using Xamarin.Forms; | |||
using eShopOnContainers.Droid.Effects; | |||
using Xamarin.Forms.Platform.Android; | |||
using System; | |||
using Android.Widget; | |||
using eShopOnContainers.Core.Effects; | |||
using System.ComponentModel; | |||
using System.Diagnostics; | |||
[assembly: ExportEffect(typeof(EntryLineColorEffect), "EntryLineColorEffect")] | |||
namespace eShopOnContainers.Droid.Effects | |||
{ | |||
public class EntryLineColorEffect : PlatformEffect | |||
{ | |||
EditText control; | |||
protected override void OnAttached() | |||
{ | |||
try | |||
{ | |||
control = Control as EditText; | |||
UpdateLineColor(); | |||
} | |||
catch (Exception ex) | |||
{ | |||
Console.WriteLine("Cannot set property on attached control. Error: ", ex.Message); | |||
} | |||
} | |||
protected override void OnDetached() | |||
{ | |||
control = null; | |||
} | |||
protected override void OnElementPropertyChanged(PropertyChangedEventArgs args) | |||
{ | |||
if (args.PropertyName == LineColorEffect.LineColorProperty.PropertyName) | |||
{ | |||
UpdateLineColor(); | |||
} | |||
} | |||
private void UpdateLineColor() | |||
{ | |||
try | |||
{ | |||
if (control != null) | |||
{ | |||
control.Background.SetColorFilter(LineColorEffect.GetLineColor(Element).ToAndroid(), Android.Graphics.PorterDuff.Mode.SrcAtop); | |||
} | |||
} | |||
catch (Exception ex) | |||
{ | |||
Debug.WriteLine(ex.Message); | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,38 @@ | |||
using Android.Views; | |||
namespace eShopOnContainers.Droid.Extensions | |||
{ | |||
internal static class ViewExtensions | |||
{ | |||
public static T FindChildOfType<T>(this ViewGroup parent) where T : View | |||
{ | |||
if (parent == null) | |||
return null; | |||
if (parent.ChildCount == 0) | |||
return null; | |||
for (var i = 0; i < parent.ChildCount; i++) | |||
{ | |||
var child = parent.GetChildAt(i); | |||
var typedChild = child as T; | |||
if (typedChild != null) | |||
{ | |||
return typedChild; | |||
} | |||
if (!(child is ViewGroup)) | |||
continue; | |||
var result = FindChildOfType<T>(child as ViewGroup); | |||
if (result != null) | |||
return result; | |||
} | |||
return null; | |||
} | |||
} | |||
} |
@ -0,0 +1,5 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> | |||
<uses-sdk android:minSdkVersion="15" /> | |||
<application android:label="eShopOnContainers.Droid"></application> | |||
</manifest> |
@ -0,0 +1,34 @@ | |||
using System.Reflection; | |||
using System.Runtime.CompilerServices; | |||
using System.Runtime.InteropServices; | |||
using Android.App; | |||
// 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("eShopOnContainers.Droid")] | |||
[assembly: AssemblyDescription("")] | |||
[assembly: AssemblyConfiguration("")] | |||
[assembly: AssemblyCompany("")] | |||
[assembly: AssemblyProduct("eShopOnContainers.Droid")] | |||
[assembly: AssemblyCopyright("Copyright © 2014")] | |||
[assembly: AssemblyTrademark("")] | |||
[assembly: AssemblyCulture("")] | |||
[assembly: ComVisible(false)] | |||
// 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")] | |||
// Add some common permissions, these can be removed if not needed | |||
[assembly: UsesPermission(Android.Manifest.Permission.Internet)] | |||
[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)] |
@ -0,0 +1,240 @@ | |||
using System; | |||
using Android.Content; | |||
using Android.Views; | |||
using Android.Widget; | |||
using Android.Graphics.Drawables; | |||
using Android.Views.Animations; | |||
using Android.Graphics.Drawables.Shapes; | |||
using Android.Util; | |||
using Android.Graphics; | |||
namespace eShopOnContainers.Droid.Renderers | |||
{ | |||
public class BadgeView : TextView | |||
{ | |||
public enum BadgePosition | |||
{ | |||
PositionTopLeft = 1, | |||
PositionTopRight = 2, | |||
PositionBottomLeft = 3, | |||
PositionBottomRight = 4, | |||
PositionCenter = 5 | |||
} | |||
private const int DefaultHmarginDip = -10; | |||
private const int DefaultVmarginDip = -5; | |||
private const int DefaultLrPaddingDip = 4; | |||
private const int DefaultCornerRadiusDip = 7; | |||
private static Animation _fadeInAnimation; | |||
private static Animation _fadeOutAnimation; | |||
private Context _context; | |||
private readonly Color _defaultBadgeColor = Color.ParseColor("#CCFF0000"); | |||
private ShapeDrawable _backgroundShape; | |||
public View Target { get; private set; } | |||
public BadgePosition Postion { get; set; } = BadgePosition.PositionTopRight; | |||
public int BadgeMarginH { get; set; } | |||
public int BadgeMarginV { get; set; } | |||
public static int TextSizeDip { get; set; } = 11; | |||
public Color BadgeColor | |||
{ | |||
get { return _backgroundShape.Paint.Color; } | |||
set | |||
{ | |||
_backgroundShape.Paint.Color = value; | |||
Background.InvalidateSelf(); | |||
} | |||
} | |||
public Color TextColor | |||
{ | |||
get { return new Color(CurrentTextColor); } | |||
set { SetTextColor(value); } | |||
} | |||
public BadgeView(Context context, View target) : this(context, null, Android.Resource.Attribute.TextViewStyle, target) | |||
{ | |||
} | |||
public BadgeView(Context context, IAttributeSet attrs, int defStyle, View target) : base(context, attrs, defStyle) | |||
{ | |||
Init(context, target); | |||
} | |||
private void Init(Context context, View target) | |||
{ | |||
_context = context; | |||
Target = target; | |||
BadgeMarginH = DipToPixels(DefaultHmarginDip); | |||
BadgeMarginV = DipToPixels(DefaultVmarginDip); | |||
Typeface = Typeface.DefaultBold; | |||
var paddingPixels = DipToPixels(DefaultLrPaddingDip); | |||
SetPadding(paddingPixels, 0, paddingPixels, 0); | |||
SetTextColor(Color.White); | |||
SetTextSize(ComplexUnitType.Dip, TextSizeDip); | |||
_fadeInAnimation = new AlphaAnimation(0, 1) | |||
{ | |||
Interpolator = new DecelerateInterpolator(), | |||
Duration = 200 | |||
}; | |||
_fadeOutAnimation = new AlphaAnimation(1, 0) | |||
{ | |||
Interpolator = new AccelerateInterpolator(), | |||
Duration = 200 | |||
}; | |||
_backgroundShape = CreateBackgroundShape(); | |||
Background = _backgroundShape; | |||
BadgeColor = _defaultBadgeColor; | |||
if (Target != null) | |||
{ | |||
ApplyTo(Target); | |||
} | |||
else | |||
{ | |||
Show(); | |||
} | |||
} | |||
private ShapeDrawable CreateBackgroundShape() | |||
{ | |||
var radius = DipToPixels(DefaultCornerRadiusDip); | |||
var outerR = new float[] { radius, radius, radius, radius, radius, radius, radius, radius }; | |||
return new ShapeDrawable(new RoundRectShape(outerR, null, null)); | |||
} | |||
private void ApplyTo(View target) | |||
{ | |||
var lp = target.LayoutParameters; | |||
var parent = target.Parent; | |||
var group = parent as ViewGroup; | |||
if (group == null) | |||
{ | |||
Console.WriteLine("Badge target parent has to be a view group"); | |||
return; | |||
} | |||
group.SetClipChildren(false); | |||
group.SetClipToPadding(false); | |||
var container = new FrameLayout(_context); | |||
var index = group.IndexOfChild(target); | |||
group.RemoveView(target); | |||
group.AddView(container, index, lp); | |||
container.AddView(target); | |||
group.Invalidate(); | |||
Visibility = ViewStates.Gone; | |||
container.AddView(this); | |||
} | |||
public void Show() | |||
{ | |||
Show(false, null); | |||
} | |||
public void Show(bool animate) | |||
{ | |||
Show(animate, _fadeInAnimation); | |||
} | |||
public void Hide(bool animate) | |||
{ | |||
Hide(animate, _fadeOutAnimation); | |||
} | |||
private void Show(bool animate, Animation anim) | |||
{ | |||
ApplyLayoutParams(); | |||
if (animate) | |||
{ | |||
StartAnimation(anim); | |||
} | |||
Visibility = ViewStates.Visible; | |||
} | |||
private void Hide(bool animate, Animation anim) | |||
{ | |||
Visibility = ViewStates.Gone; | |||
if (animate) | |||
{ | |||
StartAnimation(anim); | |||
} | |||
} | |||
private void ApplyLayoutParams() | |||
{ | |||
var layoutParameters = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent); | |||
switch (Postion) | |||
{ | |||
case BadgePosition.PositionTopLeft: | |||
layoutParameters.Gravity = GravityFlags.Left | GravityFlags.Top; | |||
layoutParameters.SetMargins(BadgeMarginH, BadgeMarginV, 0, 0); | |||
break; | |||
case BadgePosition.PositionTopRight: | |||
layoutParameters.Gravity = GravityFlags.Right | GravityFlags.Top; | |||
layoutParameters.SetMargins(0, BadgeMarginV, BadgeMarginH, 0); | |||
break; | |||
case BadgePosition.PositionBottomLeft: | |||
layoutParameters.Gravity = GravityFlags.Left | GravityFlags.Bottom; | |||
layoutParameters.SetMargins(BadgeMarginH, 0, 0, BadgeMarginV); | |||
break; | |||
case BadgePosition.PositionBottomRight: | |||
layoutParameters.Gravity = GravityFlags.Right | GravityFlags.Bottom; | |||
layoutParameters.SetMargins(0, 0, BadgeMarginH, BadgeMarginV); | |||
break; | |||
case BadgePosition.PositionCenter: | |||
layoutParameters.Gravity = GravityFlags.Center; | |||
layoutParameters.SetMargins(0, 0, 0, 0); | |||
break; | |||
} | |||
LayoutParameters = layoutParameters; | |||
} | |||
private int DipToPixels(int dip) | |||
{ | |||
return (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, dip, Resources.DisplayMetrics); | |||
} | |||
public new string Text | |||
{ | |||
get { return base.Text; } | |||
set | |||
{ | |||
base.Text = value; | |||
if (Visibility == ViewStates.Visible && string.IsNullOrEmpty(value)) | |||
{ | |||
Hide(true); | |||
} | |||
else if (Visibility == ViewStates.Gone && !string.IsNullOrEmpty(value)) | |||
{ | |||
Show(true); | |||
} | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,142 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Threading.Tasks; | |||
using Xamarin.Forms.Platform.Android.AppCompat; | |||
using Xamarin.Forms; | |||
using Android.Support.Design.Widget; | |||
using Android.Views; | |||
using Android.Widget; | |||
using Xamarin.Forms.Platform.Android; | |||
using eShopOnContainers.Droid.Extensions; | |||
using eShopOnContainers.Core.Controls; | |||
using eShopOnContainers.Droid.Renderers; | |||
[assembly: ExportRenderer(typeof(TabbedPage), typeof(CustomTabbedPageRenderer))] | |||
namespace eShopOnContainers.Droid.Renderers | |||
{ | |||
public class CustomTabbedPageRenderer : TabbedPageRenderer | |||
{ | |||
private const int DeleayBeforeTabAdded = 10; | |||
protected readonly Dictionary<Element, BadgeView> BadgeViews = new Dictionary<Element, BadgeView>(); | |||
private TabLayout _tabLayout; | |||
private TabLayout.SlidingTabStrip _tabStrip; | |||
protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e) | |||
{ | |||
base.OnElementChanged(e); | |||
_tabLayout = ViewGroup.FindChildOfType<TabLayout>(); | |||
if (_tabLayout == null) | |||
{ | |||
Console.WriteLine("No TabLayout found. Bedge not added."); | |||
return; | |||
} | |||
_tabStrip = _tabLayout.FindChildOfType<TabLayout.SlidingTabStrip>(); | |||
for (var i = 0; i < _tabLayout.TabCount; i++) | |||
{ | |||
AddTabBadge(i); | |||
} | |||
Element.ChildAdded += OnTabAdded; | |||
Element.ChildRemoved += OnTabRemoved; | |||
} | |||
private void AddTabBadge(int tabIndex) | |||
{ | |||
var element = Element.Children[tabIndex]; | |||
var view = _tabLayout?.GetTabAt(tabIndex).CustomView ?? _tabStrip?.GetChildAt(tabIndex); | |||
var badgeView = (view as ViewGroup)?.FindChildOfType<BadgeView>(); | |||
if (badgeView == null) | |||
{ | |||
var imageView = (view as ViewGroup)?.FindChildOfType<ImageView>(); | |||
var badgeTarget = imageView?.Drawable != null | |||
? (Android.Views.View)imageView | |||
: (view as ViewGroup)?.FindChildOfType<TextView>(); | |||
// Create badge for tab | |||
badgeView = new BadgeView(Context, badgeTarget); | |||
} | |||
BadgeViews[element] = badgeView; | |||
// Get text | |||
var badgeText = CustomTabbedPage.GetBadgeText(element); | |||
badgeView.Text = badgeText; | |||
// Set color if not default | |||
var tabColor = CustomTabbedPage.GetBadgeColor(element); | |||
if (tabColor != Color.Default) | |||
{ | |||
badgeView.BadgeColor = tabColor.ToAndroid(); | |||
} | |||
element.PropertyChanged += OnTabbedPagePropertyChanged; | |||
} | |||
protected virtual void OnTabbedPagePropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) | |||
{ | |||
var element = sender as Element; | |||
if (element == null) | |||
return; | |||
BadgeView badgeView; | |||
if (!BadgeViews.TryGetValue(element, out badgeView)) | |||
{ | |||
return; | |||
} | |||
if (e.PropertyName == CustomTabbedPage.BadgeTextProperty.PropertyName) | |||
{ | |||
badgeView.Text = CustomTabbedPage.GetBadgeText(element); | |||
return; | |||
} | |||
if (e.PropertyName == CustomTabbedPage.BadgeColorProperty.PropertyName) | |||
{ | |||
badgeView.BadgeColor = CustomTabbedPage.GetBadgeColor(element).ToAndroid(); | |||
} | |||
} | |||
private void OnTabRemoved(object sender, ElementEventArgs e) | |||
{ | |||
e.Element.PropertyChanged -= OnTabbedPagePropertyChanged; | |||
BadgeViews.Remove(e.Element); | |||
} | |||
private async void OnTabAdded(object sender, ElementEventArgs e) | |||
{ | |||
await Task.Delay(DeleayBeforeTabAdded); | |||
var page = e.Element as Page; | |||
if (page == null) | |||
return; | |||
var tabIndex = Element.Children.IndexOf(page); | |||
AddTabBadge(tabIndex); | |||
} | |||
protected override void Dispose(bool disposing) | |||
{ | |||
if (Element != null) | |||
{ | |||
foreach (var tab in Element.Children) | |||
{ | |||
tab.PropertyChanged -= OnTabbedPagePropertyChanged; | |||
} | |||
Element.ChildRemoved -= OnTabRemoved; | |||
Element.ChildAdded -= OnTabAdded; | |||
BadgeViews.Clear(); | |||
} | |||
base.Dispose(disposing); | |||
} | |||
} | |||
} |
@ -0,0 +1,45 @@ | |||
using SlideOverKit.Droid; | |||
using eShopOnContainers.Core.Views; | |||
using eShopOnContainers.Droid.Renderers; | |||
using System; | |||
using Xamarin.Forms; | |||
using Xamarin.Forms.Platform.Android; | |||
[assembly: ExportRenderer(typeof(HomeView), typeof(SlideDownMenuPageRenderer))] | |||
namespace eShopOnContainers.Droid.Renderers | |||
{ | |||
public class SlideDownMenuPageRenderer : PageRenderer, ISlideOverKitPageRendererDroid | |||
{ | |||
public Action<ElementChangedEventArgs<Page>> OnElementChangedEvent { get; set; } | |||
public Action<bool, int, int, int, int> OnLayoutEvent { get; set; } | |||
public Action<int, int, int, int> OnSizeChangedEvent { get; set; } | |||
public SlideDownMenuPageRenderer() | |||
{ | |||
new SlideOverKitDroidHandler().Init(this); | |||
} | |||
protected override void OnElementChanged(ElementChangedEventArgs<Page> e) | |||
{ | |||
base.OnElementChanged(e); | |||
if (OnElementChangedEvent != null) | |||
OnElementChangedEvent(e); | |||
} | |||
protected override void OnLayout(bool changed, int l, int t, int r, int b) | |||
{ | |||
base.OnLayout(changed, l, t, r, b); | |||
if (OnLayoutEvent != null) | |||
OnLayoutEvent(changed, l, t, r, b); | |||
} | |||
protected override void OnSizeChanged(int w, int h, int oldw, int oldh) | |||
{ | |||
base.OnSizeChanged(w, h, oldw, oldh); | |||
if (OnSizeChangedEvent != null) | |||
OnSizeChangedEvent(w, h, oldw, oldh); | |||
} | |||
} | |||
} |
@ -0,0 +1,50 @@ | |||
Images, layout descriptions, binary blobs and string dictionaries can be included | |||
in your application as resource files. Various Android APIs are designed to | |||
operate on the resource IDs instead of dealing with images, strings or binary blobs | |||
directly. | |||
For example, a sample Android app that contains a user interface layout (main.xml), | |||
an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) | |||
would keep its resources in the "Resources" directory of the application: | |||
Resources/ | |||
drawable-hdpi/ | |||
icon.png | |||
drawable-ldpi/ | |||
icon.png | |||
drawable-mdpi/ | |||
icon.png | |||
layout/ | |||
main.xml | |||
values/ | |||
strings.xml | |||
In order to get the build system to recognize Android resources, set the build action to | |||
"AndroidResource". The native Android APIs do not operate directly with filenames, but | |||
instead operate on resource IDs. When you compile an Android application that uses resources, | |||
the build system will package the resources for distribution and generate a class called | |||
"Resource" that contains the tokens for each one of the resources included. For example, | |||
for the above Resources layout, this is what the Resource class would expose: | |||
public class Resource { | |||
public class drawable { | |||
public const int icon = 0x123; | |||
} | |||
public class layout { | |||
public const int main = 0x456; | |||
} | |||
public class strings { | |||
public const int first_string = 0xabc; | |||
public const int second_string = 0xbcd; | |||
} | |||
} | |||
You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main | |||
to reference the layout/main.xml file, or Resource.strings.first_string to reference the first | |||
string in the dictionary file values/strings.xml. |