├── .github
└── workflows
│ └── build-validation.yml
├── .gitignore
├── Art
├── CodedMonkeys.png
├── Convert.PNG
├── Details.PNG
├── EmptyView.png
├── FinalUI.PNG
├── GridItemsLayoutHorizontal.png
├── GridItemsLayoutVert.png
├── PullToRefresh.PNG
├── ResourcesSingleProject.png
├── RestoreNuGets.PNG
├── SelectFramework.png
├── Solution.PNG
└── Themes.gif
├── Community Modules
└── README.md
├── Directory.build.props
├── Directory.build.targets
├── Finish
├── MonkeyFinder.sln
└── MonkeyFinder
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── AppShell.xaml
│ ├── AppShell.xaml.cs
│ ├── GlobalUsings.cs
│ ├── MauiProgram.cs
│ ├── Model
│ └── Monkey.cs
│ ├── MonkeyFinder.csproj
│ ├── Platforms
│ ├── Android
│ │ ├── AndroidManifest.xml
│ │ ├── AssemblyInfo.cs
│ │ ├── MainActivity.cs
│ │ ├── MainApplication.cs
│ │ └── Resources
│ │ │ └── values
│ │ │ └── colors.xml
│ ├── MacCatalyst
│ │ ├── AppDelegate.cs
│ │ ├── Info.plist
│ │ └── Program.cs
│ ├── Windows
│ │ ├── App.xaml
│ │ ├── App.xaml.cs
│ │ ├── Package.appxmanifest
│ │ └── app.manifest
│ └── iOS
│ │ ├── AppDelegate.cs
│ │ ├── Info.plist
│ │ └── Program.cs
│ ├── Properties
│ └── launchSettings.json
│ ├── Resources
│ ├── Fonts
│ │ └── OpenSans-Regular.ttf
│ ├── Images
│ │ ├── dotnet_bot.svg
│ │ └── nodata.png
│ ├── Raw
│ │ ├── AboutAssets.txt
│ │ └── monkeydata.json
│ ├── appicon.svg
│ └── appiconfg.svg
│ ├── Services
│ └── MonkeyService.cs
│ ├── View
│ ├── DetailsPage.xaml
│ ├── DetailsPage.xaml.cs
│ ├── MainPage.xaml
│ └── MainPage.xaml.cs
│ └── ViewModel
│ ├── BaseViewModel.cs
│ ├── MonkeyDetailsViewModel.cs
│ └── MonkeysViewModel.cs
├── LICENSE
├── Part 0 - Overview
├── README.md
├── README.zh-cn.md
└── README.zh-tw.md
├── Part 1 - Displaying Data
├── MonkeyFinder.sln
├── MonkeyFinder
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── AppShell.xaml
│ ├── AppShell.xaml.cs
│ ├── GlobalUsings.cs
│ ├── MauiProgram.cs
│ ├── Model
│ │ └── Monkey.cs
│ ├── MonkeyFinder.csproj
│ ├── Platforms
│ │ ├── Android
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── AssemblyInfo.cs
│ │ │ ├── MainActivity.cs
│ │ │ ├── MainApplication.cs
│ │ │ └── Resources
│ │ │ │ └── values
│ │ │ │ └── colors.xml
│ │ ├── MacCatalyst
│ │ │ ├── AppDelegate.cs
│ │ │ ├── Info.plist
│ │ │ └── Program.cs
│ │ ├── Windows
│ │ │ ├── App.xaml
│ │ │ ├── App.xaml.cs
│ │ │ ├── Package.appxmanifest
│ │ │ └── app.manifest
│ │ └── iOS
│ │ │ ├── AppDelegate.cs
│ │ │ ├── Info.plist
│ │ │ └── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── Resources
│ │ ├── Fonts
│ │ │ └── OpenSans-Regular.ttf
│ │ ├── Images
│ │ │ ├── dotnet_bot.svg
│ │ │ └── nodata.png
│ │ ├── Raw
│ │ │ ├── AboutAssets.txt
│ │ │ └── monkeydata.json
│ │ ├── appicon.svg
│ │ └── appiconfg.svg
│ ├── Services
│ │ └── MonkeyService.cs
│ ├── View
│ │ ├── DetailsPage.xaml
│ │ ├── DetailsPage.xaml.cs
│ │ ├── MainPage.xaml
│ │ └── MainPage.xaml.cs
│ └── ViewModel
│ │ ├── BaseViewModel.cs
│ │ ├── MonkeyDetailsViewModel.cs
│ │ └── MonkeysViewModel.cs
├── README.md
├── README.zh-cn.md
└── README.zh-tw.md
├── Part 2 - MVVM
├── MonkeyFinder.sln
├── MonkeyFinder
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── AppShell.xaml
│ ├── AppShell.xaml.cs
│ ├── GlobalUsings.cs
│ ├── MauiProgram.cs
│ ├── Model
│ │ └── Monkey.cs
│ ├── MonkeyFinder.csproj
│ ├── Platforms
│ │ ├── Android
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── AssemblyInfo.cs
│ │ │ ├── MainActivity.cs
│ │ │ ├── MainApplication.cs
│ │ │ └── Resources
│ │ │ │ └── values
│ │ │ │ └── colors.xml
│ │ ├── MacCatalyst
│ │ │ ├── AppDelegate.cs
│ │ │ ├── Info.plist
│ │ │ └── Program.cs
│ │ ├── Windows
│ │ │ ├── App.xaml
│ │ │ ├── App.xaml.cs
│ │ │ ├── Package.appxmanifest
│ │ │ └── app.manifest
│ │ └── iOS
│ │ │ ├── AppDelegate.cs
│ │ │ ├── Info.plist
│ │ │ └── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── Resources
│ │ ├── Fonts
│ │ │ └── OpenSans-Regular.ttf
│ │ ├── Images
│ │ │ ├── dotnet_bot.svg
│ │ │ └── nodata.png
│ │ ├── Raw
│ │ │ ├── AboutAssets.txt
│ │ │ └── monkeydata.json
│ │ ├── appicon.svg
│ │ └── appiconfg.svg
│ ├── Services
│ │ └── MonkeyService.cs
│ ├── View
│ │ ├── DetailsPage.xaml
│ │ ├── DetailsPage.xaml.cs
│ │ ├── MainPage.xaml
│ │ └── MainPage.xaml.cs
│ └── ViewModel
│ │ ├── BaseViewModel.cs
│ │ ├── MonkeyDetailsViewModel.cs
│ │ └── MonkeysViewModel.cs
├── README.md
├── README.zh-cn.md
└── README.zh-tw.md
├── Part 3 - Navigation
├── MonkeyFinder.sln
├── MonkeyFinder
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── AppShell.xaml
│ ├── AppShell.xaml.cs
│ ├── GlobalUsings.cs
│ ├── MauiProgram.cs
│ ├── Model
│ │ └── Monkey.cs
│ ├── MonkeyFinder.csproj
│ ├── Platforms
│ │ ├── Android
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── AssemblyInfo.cs
│ │ │ ├── MainActivity.cs
│ │ │ ├── MainApplication.cs
│ │ │ └── Resources
│ │ │ │ └── values
│ │ │ │ └── colors.xml
│ │ ├── MacCatalyst
│ │ │ ├── AppDelegate.cs
│ │ │ ├── Info.plist
│ │ │ └── Program.cs
│ │ ├── Windows
│ │ │ ├── App.xaml
│ │ │ ├── App.xaml.cs
│ │ │ ├── Package.appxmanifest
│ │ │ └── app.manifest
│ │ └── iOS
│ │ │ ├── AppDelegate.cs
│ │ │ ├── Info.plist
│ │ │ └── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── Resources
│ │ ├── Fonts
│ │ │ └── OpenSans-Regular.ttf
│ │ ├── Images
│ │ │ ├── dotnet_bot.svg
│ │ │ └── nodata.png
│ │ ├── Raw
│ │ │ ├── AboutAssets.txt
│ │ │ └── monkeydata.json
│ │ ├── appicon.svg
│ │ └── appiconfg.svg
│ ├── Services
│ │ └── MonkeyService.cs
│ ├── View
│ │ ├── DetailsPage.xaml
│ │ ├── DetailsPage.xaml.cs
│ │ ├── MainPage.xaml
│ │ └── MainPage.xaml.cs
│ └── ViewModel
│ │ ├── BaseViewModel.cs
│ │ ├── MonkeyDetailsViewModel.cs
│ │ └── MonkeysViewModel.cs
├── README.md
├── README.zh-cn.md
└── README.zh-tw.md
├── Part 4 - Platform Features
├── MonkeyFinder.sln
├── MonkeyFinder
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── AppShell.xaml
│ ├── AppShell.xaml.cs
│ ├── GlobalUsings.cs
│ ├── MauiProgram.cs
│ ├── Model
│ │ └── Monkey.cs
│ ├── MonkeyFinder.csproj
│ ├── Platforms
│ │ ├── Android
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── AssemblyInfo.cs
│ │ │ ├── MainActivity.cs
│ │ │ ├── MainApplication.cs
│ │ │ └── Resources
│ │ │ │ └── values
│ │ │ │ └── colors.xml
│ │ ├── MacCatalyst
│ │ │ ├── AppDelegate.cs
│ │ │ ├── Info.plist
│ │ │ └── Program.cs
│ │ ├── Windows
│ │ │ ├── App.xaml
│ │ │ ├── App.xaml.cs
│ │ │ ├── Package.appxmanifest
│ │ │ └── app.manifest
│ │ └── iOS
│ │ │ ├── AppDelegate.cs
│ │ │ ├── Info.plist
│ │ │ └── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── Resources
│ │ ├── Fonts
│ │ │ └── OpenSans-Regular.ttf
│ │ ├── Images
│ │ │ ├── dotnet_bot.svg
│ │ │ └── nodata.png
│ │ ├── Raw
│ │ │ ├── AboutAssets.txt
│ │ │ └── monkeydata.json
│ │ ├── appicon.svg
│ │ └── appiconfg.svg
│ ├── Services
│ │ └── MonkeyService.cs
│ ├── View
│ │ ├── DetailsPage.xaml
│ │ ├── DetailsPage.xaml.cs
│ │ ├── MainPage.xaml
│ │ └── MainPage.xaml.cs
│ └── ViewModel
│ │ ├── BaseViewModel.cs
│ │ ├── MonkeyDetailsViewModel.cs
│ │ └── MonkeysViewModel.cs
├── README.md
├── README.zh-cn.md
└── README.zh-tw.md
├── Part 5 - CollectionView
├── MonkeyFinder.sln
├── MonkeyFinder
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── AppShell.xaml
│ ├── AppShell.xaml.cs
│ ├── GlobalUsings.cs
│ ├── MauiProgram.cs
│ ├── Model
│ │ └── Monkey.cs
│ ├── MonkeyFinder.csproj
│ ├── Platforms
│ │ ├── Android
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── AssemblyInfo.cs
│ │ │ ├── MainActivity.cs
│ │ │ ├── MainApplication.cs
│ │ │ └── Resources
│ │ │ │ └── values
│ │ │ │ └── colors.xml
│ │ ├── MacCatalyst
│ │ │ ├── AppDelegate.cs
│ │ │ ├── Info.plist
│ │ │ └── Program.cs
│ │ ├── Windows
│ │ │ ├── App.xaml
│ │ │ ├── App.xaml.cs
│ │ │ ├── Package.appxmanifest
│ │ │ └── app.manifest
│ │ └── iOS
│ │ │ ├── AppDelegate.cs
│ │ │ ├── Info.plist
│ │ │ └── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── Resources
│ │ ├── Fonts
│ │ │ └── OpenSans-Regular.ttf
│ │ ├── Images
│ │ │ ├── dotnet_bot.svg
│ │ │ └── nodata.png
│ │ ├── Raw
│ │ │ ├── AboutAssets.txt
│ │ │ └── monkeydata.json
│ │ ├── appicon.svg
│ │ └── appiconfg.svg
│ ├── Services
│ │ └── MonkeyService.cs
│ ├── View
│ │ ├── DetailsPage.xaml
│ │ ├── DetailsPage.xaml.cs
│ │ ├── MainPage.xaml
│ │ └── MainPage.xaml.cs
│ └── ViewModel
│ │ ├── BaseViewModel.cs
│ │ ├── MonkeyDetailsViewModel.cs
│ │ └── MonkeysViewModel.cs
├── README.md
├── README.zh-cn.md
└── README.zh-tw.md
├── Part 6 - AppThemes
├── MonkeyFinder.sln
├── MonkeyFinder
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── AppShell.xaml
│ ├── AppShell.xaml.cs
│ ├── GlobalUsings.cs
│ ├── MauiProgram.cs
│ ├── Model
│ │ └── Monkey.cs
│ ├── MonkeyFinder.csproj
│ ├── Platforms
│ │ ├── Android
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── AssemblyInfo.cs
│ │ │ ├── MainActivity.cs
│ │ │ ├── MainApplication.cs
│ │ │ └── Resources
│ │ │ │ └── values
│ │ │ │ └── colors.xml
│ │ ├── MacCatalyst
│ │ │ ├── AppDelegate.cs
│ │ │ ├── Info.plist
│ │ │ └── Program.cs
│ │ ├── Windows
│ │ │ ├── App.xaml
│ │ │ ├── App.xaml.cs
│ │ │ ├── Package.appxmanifest
│ │ │ └── app.manifest
│ │ └── iOS
│ │ │ ├── AppDelegate.cs
│ │ │ ├── Info.plist
│ │ │ └── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── Resources
│ │ ├── Fonts
│ │ │ └── OpenSans-Regular.ttf
│ │ ├── Images
│ │ │ ├── dotnet_bot.svg
│ │ │ └── nodata.png
│ │ ├── Raw
│ │ │ ├── AboutAssets.txt
│ │ │ └── monkeydata.json
│ │ ├── appicon.svg
│ │ └── appiconfg.svg
│ ├── Services
│ │ └── MonkeyService.cs
│ ├── View
│ │ ├── DetailsPage.xaml
│ │ ├── DetailsPage.xaml.cs
│ │ ├── MainPage.xaml
│ │ └── MainPage.xaml.cs
│ └── ViewModel
│ │ ├── BaseViewModel.cs
│ │ ├── MonkeyDetailsViewModel.cs
│ │ └── MonkeysViewModel.cs
├── README.md
├── README.zh-cn.md
└── README.zh-tw.md
├── README.md
├── README.zh-cn.md
├── README.zh-tw.md
└── Slides
├── Workshop0 - Introduction to .NET MAUI.pptx
├── Workshop1 - Our First App.pptx
├── Workshop2 - MVVM and Data Binding.pptx
├── Workshop3 - Navigation.pptx
├── Workshop4 - Accessing Platform Features.pptx
├── Workshop5 - CollectionView.pptx
└── Workshop6 - App Themes.pptx
/.github/workflows/build-validation.yml:
--------------------------------------------------------------------------------
1 | name: build
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | paths:
7 | - '**.cs'
8 | - '**.csproj'
9 | - '**.xaml'
10 | pull_request:
11 | branches: [ main ]
12 | paths:
13 | - '**.cs'
14 | - '**.csproj'
15 | - '**.xaml'
16 |
17 | env:
18 | DOTNET_VERSION: '6.0.x' # The .NET SDK version to use
19 |
20 | jobs:
21 | build:
22 |
23 | name: Build All Projects
24 | runs-on: windows-latest
25 |
26 | strategy:
27 | fail-fast: false
28 | matrix:
29 | project:
30 | - Part 1 - Displaying Data
31 | - Part 2 - MVVM
32 | - Part 3 - Navigation
33 | - Part 4 - Platform Features
34 | - Part 5 - CollectionView
35 | - Part 6 - AppThemes
36 |
37 | steps:
38 | - uses: actions/checkout@v3
39 | - name: Setup .NET
40 | uses: actions/setup-dotnet@v2
41 | with:
42 | dotnet-version: ${{ env.DOTNET_VERSION }}
43 |
44 | - name: Setup MSBuild.exe
45 | uses: microsoft/setup-msbuild@v1.1
46 | with:
47 | vs-prerelease: true
48 |
49 | - name: Install .NET workloads
50 | shell: pwsh
51 | run: |
52 | dotnet workload install android
53 | dotnet workload install ios
54 | dotnet workload install maccatalyst
55 | dotnet workload install maui
56 |
57 | - name: Build ${{ matrix.project }}
58 | run: dotnet build "${{ matrix.project }}/MonkeyFinder/MonkeyFinder.csproj"
59 |
--------------------------------------------------------------------------------
/Art/CodedMonkeys.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Art/CodedMonkeys.png
--------------------------------------------------------------------------------
/Art/Convert.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Art/Convert.PNG
--------------------------------------------------------------------------------
/Art/Details.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Art/Details.PNG
--------------------------------------------------------------------------------
/Art/EmptyView.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Art/EmptyView.png
--------------------------------------------------------------------------------
/Art/FinalUI.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Art/FinalUI.PNG
--------------------------------------------------------------------------------
/Art/GridItemsLayoutHorizontal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Art/GridItemsLayoutHorizontal.png
--------------------------------------------------------------------------------
/Art/GridItemsLayoutVert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Art/GridItemsLayoutVert.png
--------------------------------------------------------------------------------
/Art/PullToRefresh.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Art/PullToRefresh.PNG
--------------------------------------------------------------------------------
/Art/ResourcesSingleProject.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Art/ResourcesSingleProject.png
--------------------------------------------------------------------------------
/Art/RestoreNuGets.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Art/RestoreNuGets.PNG
--------------------------------------------------------------------------------
/Art/SelectFramework.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Art/SelectFramework.png
--------------------------------------------------------------------------------
/Art/Solution.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Art/Solution.PNG
--------------------------------------------------------------------------------
/Art/Themes.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Art/Themes.gif
--------------------------------------------------------------------------------
/Community Modules/README.md:
--------------------------------------------------------------------------------
1 | # Community Workshop Modules
2 |
3 | Here you will find additional modules that build upon the completed workshop application that highlight different features and capabilities from the community. This may include how to implement new architecture, use a different testing framework, or integrate a third party control from the community or a control vendor. Each module is built to showcase a unique capability with .NET MAUI and the .NET ecosystem and can be completed standalone or when you finish the main workshop. These modules are maintained by the original author of the community module. If you run into an issue please open a new issue with the "Community Module Issue" on GitHub.
4 |
5 | ## Available Modules
6 |
7 | Coming soon!
8 |
9 | ## Contributing Modules
10 |
11 | So, you have an awesome library, component, or architecture pattern that you want to showcase in the .NET MAUI workshop? Then you are in the right place because you can contribute your very own community module right here! Before you do though, be sure to follow these instructions:
12 |
13 | 1. Open a new issue with your idea for the community module. This issue should outline what the module will be about, if their are any account creation requirements, and what the main steps of the module will be.
14 | 2. Once approved, work on your module and adhear to the same pattern as the main workshop giving developers are starting point and walking them through adding the functionality.
15 | 3. Ensure a slide deck is included with your module.
16 | 4. Create a PR with your module in the "Community Modules" folder.
17 | 5. Work with the workshop maintainers to get your PR approved and just like that your module will be live!
18 |
19 | By creating a community module you are signing up to keep your module up to date with the latest versions of .NET MAUI, other 3rd party packages, and any other changes that may need to be adjusted over time. Failure to update a module or respond to feedback/issues on GitHub will result in your module being archived. If this all sounds good to you and you are ready to get rolling then open up that issue with your community module.
20 |
--------------------------------------------------------------------------------
/Directory.build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | 14.2
4 | 14.0
5 | 21.0
6 | 10.0.17763.0
7 | 10.0.17763.0
8 |
9 |
--------------------------------------------------------------------------------
/Directory.build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.31611.283
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonkeyFinder", "MonkeyFinder\MonkeyFinder.csproj", "{C60F2B1C-790E-4432-A719-52182A333ADE}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{393B8F30-F402-46A9-B209-8C71897A3416}"
9 | ProjectSection(SolutionItems) = preProject
10 | ..\Directory.build.props = ..\Directory.build.props
11 | ..\Directory.build.targets = ..\Directory.build.targets
12 | EndProjectSection
13 | EndProject
14 | Global
15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 | Debug|Any CPU = Debug|Any CPU
17 | Release|Any CPU = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
23 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.ActiveCfg = Release|Any CPU
24 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.Build.0 = Release|Any CPU
25 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.Deploy.0 = Release|Any CPU
26 | EndGlobalSection
27 | GlobalSection(SolutionProperties) = preSolution
28 | HideSolutionNode = FALSE
29 | EndGlobalSection
30 | GlobalSection(ExtensibilityGlobals) = postSolution
31 | SolutionGuid = {61F7FB11-1E47-470C-91E2-47F8143E1572}
32 | EndGlobalSection
33 | EndGlobal
34 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/App.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class App : Application
4 | {
5 | public App()
6 | {
7 | InitializeComponent();
8 |
9 | MainPage = new AppShell();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/AppShell.xaml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/AppShell.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class AppShell : Shell
4 | {
5 | public AppShell()
6 | {
7 | InitializeComponent();
8 |
9 | Routing.RegisterRoute(nameof(DetailsPage), typeof(DetailsPage));
10 | }
11 | }
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using CommunityToolkit.Mvvm.ComponentModel;
2 | global using CommunityToolkit.Mvvm.Input;
3 | global using MonkeyFinder.Model;
4 | global using MonkeyFinder.ViewModel;
5 | global using System.Collections.ObjectModel;
6 | global using System.ComponentModel;
7 | global using System.Diagnostics;
8 | global using System.Runtime.CompilerServices;
9 | global using System.Text.Json;
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/MauiProgram.cs:
--------------------------------------------------------------------------------
1 | using MonkeyFinder.Services;
2 | using MonkeyFinder.View;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public static class MauiProgram
7 | {
8 | public static MauiApp CreateMauiApp()
9 | {
10 | var builder = MauiApp.CreateBuilder();
11 | builder
12 | .UseMauiApp()
13 | .ConfigureFonts(fonts =>
14 | {
15 | fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
16 | });
17 |
18 | builder.Services.AddSingleton(Connectivity.Current);
19 | builder.Services.AddSingleton(Geolocation.Default);
20 | builder.Services.AddSingleton(Map.Default);
21 |
22 | builder.Services.AddSingleton();
23 | builder.Services.AddSingleton();
24 | builder.Services.AddSingleton();
25 |
26 | builder.Services.AddTransient();
27 | builder.Services.AddTransient();
28 |
29 | return builder.Build();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Model/Monkey.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.Model;
2 |
3 | public class Monkey
4 | {
5 | public string Name { get; set; }
6 | public string Location { get; set; }
7 | public string Details { get; set; }
8 | public string Image { get; set; }
9 | public int Population { get; set; }
10 | public double Latitude { get; set; }
11 | public double Longitude { get; set; }
12 | }
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/MonkeyFinder.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0-android;net6.0-ios;net6.0-maccatalyst
5 | $(TargetFrameworks);net6.0-windows10.0.19041
6 | Exe
7 | MonkeyFinder
8 | true
9 | true
10 | enable
11 |
12 |
13 | MonkeyFinder
14 |
15 |
16 | com.companyname.monkeyfinder
17 | ECD44DAE-B03E-4D8B-B427-71865961E696
18 |
19 |
20 | 1.0
21 | 1
22 |
23 |
24 | True
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Platforms/Android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Platforms/Android/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 |
3 |
4 | [assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)]
5 | [assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)]
6 | [assembly: UsesFeature("android.hardware.location", Required = false)]
7 | [assembly: UsesFeature("android.hardware.location.gps", Required = false)]
8 | [assembly: UsesFeature("android.hardware.location.network", Required = false)]
9 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)]
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Platforms/Android/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Content.PM;
3 | using Android.OS;
4 |
5 | namespace MonkeyFinder;
6 |
7 | [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
8 | public class MainActivity : MauiAppCompatActivity
9 | {
10 | }
11 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Platforms/Android/MainApplication.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Runtime;
3 |
4 | namespace MonkeyFinder;
5 |
6 | [Application]
7 | public class MainApplication : MauiApplication
8 | {
9 | public MainApplication(IntPtr handle, JniHandleOwnership ownership)
10 | : base(handle, ownership)
11 | {
12 | }
13 |
14 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
15 | }
16 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Platforms/Android/Resources/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #512BD4
4 | #2B0B98
5 | #2B0B98
6 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Platforms/MacCatalyst/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 |
3 | namespace MonkeyFinder;
4 |
5 | [Register("AppDelegate")]
6 | public class AppDelegate : MauiUIApplicationDelegate
7 | {
8 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
9 | }
10 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Platforms/MacCatalyst/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIDeviceFamily
6 |
7 | 1
8 | 2
9 |
10 | UIRequiredDeviceCapabilities
11 |
12 | arm64
13 |
14 | UISupportedInterfaceOrientations
15 |
16 | UIInterfaceOrientationPortrait
17 | UIInterfaceOrientationLandscapeLeft
18 | UIInterfaceOrientationLandscapeRight
19 |
20 | UISupportedInterfaceOrientations~ipad
21 |
22 | UIInterfaceOrientationPortrait
23 | UIInterfaceOrientationPortraitUpsideDown
24 | UIInterfaceOrientationLandscapeLeft
25 | UIInterfaceOrientationLandscapeRight
26 |
27 | XSAppIconAssets
28 | Assets.xcassets/appicon.appiconset
29 | NSLocationWhenInUseUsageDescription
30 | Need to find monkeys!
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Platforms/MacCatalyst/Program.cs:
--------------------------------------------------------------------------------
1 | using ObjCRuntime;
2 | using UIKit;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public class Program
7 | {
8 | // This is the main entry point of the application.
9 | static void Main(string[] args)
10 | {
11 | // if you want to use a different Application Delegate class from "AppDelegate"
12 | // you can specify it here.
13 | UIApplication.Main(args, null, typeof(AppDelegate));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Platforms/Windows/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Platforms/Windows/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 |
3 | // To learn more about WinUI, the WinUI project structure,
4 | // and more about our project templates, see: http://aka.ms/winui-project-info.
5 |
6 | namespace MonkeyFinder.WinUI;
7 |
8 | ///
9 | /// Provides application-specific behavior to supplement the default Application class.
10 | ///
11 | public partial class App : MauiWinUIApplication
12 | {
13 | ///
14 | /// Initializes the singleton application object. This is the first line of authored code
15 | /// executed, and as such is the logical equivalent of main() or WinMain().
16 | ///
17 | public App()
18 | {
19 | this.InitializeComponent();
20 | }
21 |
22 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Platforms/Windows/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 | MonkeyFinder
16 | Microsoft
17 | appiconStoreLogo.png
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
39 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Platforms/Windows/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 | true/PM
12 | PerMonitorV2, PerMonitor
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Platforms/iOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 |
3 | namespace MonkeyFinder;
4 |
5 | [Register("AppDelegate")]
6 | public class AppDelegate : MauiUIApplicationDelegate
7 | {
8 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
9 | }
10 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Platforms/iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | LSRequiresIPhoneOS
6 |
7 | UIDeviceFamily
8 |
9 | 1
10 | 2
11 |
12 | UIRequiredDeviceCapabilities
13 |
14 | arm64
15 |
16 | UISupportedInterfaceOrientations
17 |
18 | UIInterfaceOrientationPortrait
19 | UIInterfaceOrientationLandscapeLeft
20 | UIInterfaceOrientationLandscapeRight
21 |
22 | UISupportedInterfaceOrientations~ipad
23 |
24 | UIInterfaceOrientationPortrait
25 | UIInterfaceOrientationPortraitUpsideDown
26 | UIInterfaceOrientationLandscapeLeft
27 | UIInterfaceOrientationLandscapeRight
28 |
29 | XSAppIconAssets
30 | Assets.xcassets/appicon.appiconset
31 | NSLocationWhenInUseUsageDescription
32 | Need to find monkeys!
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Platforms/iOS/Program.cs:
--------------------------------------------------------------------------------
1 | using ObjCRuntime;
2 | using UIKit;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public class Program
7 | {
8 | // This is the main entry point of the application.
9 | static void Main(string[] args)
10 | {
11 | // if you want to use a different Application Delegate class from "AppDelegate"
12 | // you can specify it here.
13 | UIApplication.Main(args, null, typeof(AppDelegate));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "Windows Machine": {
4 | "commandName": "MsixPackage",
5 | "nativeDebugging": false
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Resources/Fonts/OpenSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Finish/MonkeyFinder/Resources/Fonts/OpenSans-Regular.ttf
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Resources/Images/nodata.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Finish/MonkeyFinder/Resources/Images/nodata.png
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Resources/Raw/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories) and given a Build Action of "MauiAsset":
3 |
4 |
5 |
6 | These files will be deployed with you package and will be accessible using .NET MAUI:
7 |
8 | async Task LoadMauiAsset()
9 | {
10 | using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
11 | using var reader = new StreamReader(stream);
12 |
13 | var contents = reader.ReadToEnd();
14 | }
15 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Resources/appicon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Resources/appiconfg.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/Services/MonkeyService.cs:
--------------------------------------------------------------------------------
1 | using System.Net.Http.Json;
2 |
3 | namespace MonkeyFinder.Services;
4 |
5 | public class MonkeyService
6 | {
7 | HttpClient httpClient;
8 | public MonkeyService()
9 | {
10 | this.httpClient = new HttpClient();
11 | }
12 |
13 | List monkeyList;
14 | public async Task> GetMonkeys()
15 | {
16 | if (monkeyList?.Count > 0)
17 | return monkeyList;
18 |
19 | // Online
20 | var response = await httpClient.GetAsync("https://www.montemagno.com/monkeys.json");
21 | if (response.IsSuccessStatusCode)
22 | {
23 | monkeyList = await response.Content.ReadFromJsonAsync>();
24 | }
25 | // Offline
26 | /*using var stream = await FileSystem.OpenAppPackageFileAsync("monkeydata.json");
27 | using var reader = new StreamReader(stream);
28 | var contents = await reader.ReadToEndAsync();
29 | monkeyList = JsonSerializer.Deserialize>(contents);
30 | */
31 | return monkeyList;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/View/DetailsPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
17 |
27 |
34 |
35 |
36 |
37 |
38 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/View/DetailsPage.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class DetailsPage : ContentPage
4 | {
5 | public DetailsPage(MonkeyDetailsViewModel viewModel)
6 | {
7 | InitializeComponent();
8 | BindingContext = viewModel;
9 | }
10 | }
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/View/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.View;
2 |
3 | public partial class MainPage : ContentPage
4 | {
5 | public MainPage(MonkeysViewModel viewModel)
6 | {
7 | InitializeComponent();
8 | BindingContext = viewModel;
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/ViewModel/BaseViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.ViewModel;
2 |
3 | public partial class BaseViewModel : ObservableObject
4 | {
5 | [ObservableProperty]
6 | [NotifyPropertyChangedFor(nameof(IsNotBusy))]
7 | bool isBusy;
8 |
9 | [ObservableProperty]
10 | string title;
11 |
12 | public bool IsNotBusy => !IsBusy;
13 | }
14 |
--------------------------------------------------------------------------------
/Finish/MonkeyFinder/ViewModel/MonkeyDetailsViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.ViewModel;
2 |
3 | [QueryProperty(nameof(Monkey), "Monkey")]
4 | public partial class MonkeyDetailsViewModel : BaseViewModel
5 | {
6 | IMap map;
7 | public MonkeyDetailsViewModel(IMap map)
8 | {
9 | this.map = map;
10 | }
11 |
12 | [ObservableProperty]
13 | Monkey monkey;
14 |
15 | [RelayCommand]
16 | async Task OpenMap()
17 | {
18 | try
19 | {
20 | await map.OpenAsync(Monkey.Latitude, Monkey.Longitude, new MapLaunchOptions
21 | {
22 | Name = Monkey.Name,
23 | NavigationMode = NavigationMode.None
24 | });
25 | }
26 | catch (Exception ex)
27 | {
28 | Debug.WriteLine($"Unable to launch maps: {ex.Message}");
29 | await Shell.Current.DisplayAlert("Error, no Maps app!", ex.Message, "OK");
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 .NET Presentations: Events in a Box!
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.31611.283
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonkeyFinder", "MonkeyFinder\MonkeyFinder.csproj", "{C60F2B1C-790E-4432-A719-52182A333ADE}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{393B8F30-F402-46A9-B209-8C71897A3416}"
9 | ProjectSection(SolutionItems) = preProject
10 | ..\Directory.build.props = ..\Directory.build.props
11 | ..\Directory.build.targets = ..\Directory.build.targets
12 | README.md = README.md
13 | EndProjectSection
14 | EndProject
15 | Global
16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 | Debug|Any CPU = Debug|Any CPU
18 | Release|Any CPU = Release|Any CPU
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
24 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.Deploy.0 = Release|Any CPU
27 | EndGlobalSection
28 | GlobalSection(SolutionProperties) = preSolution
29 | HideSolutionNode = FALSE
30 | EndGlobalSection
31 | GlobalSection(ExtensibilityGlobals) = postSolution
32 | SolutionGuid = {61F7FB11-1E47-470C-91E2-47F8143E1572}
33 | EndGlobalSection
34 | EndGlobal
35 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/App.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class App : Application
4 | {
5 | public App()
6 | {
7 | InitializeComponent();
8 |
9 | MainPage = new AppShell();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/AppShell.xaml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/AppShell.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class AppShell : Shell
4 | {
5 | public AppShell()
6 | {
7 | InitializeComponent();
8 | }
9 | }
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using CommunityToolkit.Mvvm.ComponentModel;
2 | global using CommunityToolkit.Mvvm.Input;
3 | global using MonkeyFinder.Model;
4 | global using MonkeyFinder.ViewModel;
5 | global using System.Collections.ObjectModel;
6 | global using System.ComponentModel;
7 | global using System.Diagnostics;
8 | global using System.Runtime.CompilerServices;
9 | global using System.Text.Json;
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/MauiProgram.cs:
--------------------------------------------------------------------------------
1 | using MonkeyFinder.View;
2 |
3 | namespace MonkeyFinder;
4 |
5 | public static class MauiProgram
6 | {
7 | public static MauiApp CreateMauiApp()
8 | {
9 | var builder = MauiApp.CreateBuilder();
10 | builder
11 | .UseMauiApp()
12 | .ConfigureFonts(fonts =>
13 | {
14 | fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
15 | });
16 |
17 | builder.Services.AddSingleton();
18 |
19 | return builder.Build();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Model/Monkey.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.Model;
2 |
3 | public class Monkey
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/MonkeyFinder.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0-android;net6.0-ios;net6.0-maccatalyst
5 | $(TargetFrameworks);net6.0-windows10.0.19041
6 | Exe
7 | MonkeyFinder
8 | true
9 | true
10 | enable
11 |
12 |
13 | MonkeyFinder
14 |
15 |
16 | com.companyname.monkeyfinder
17 | ECD44DAE-B03E-4D8B-B427-71865961E696
18 |
19 |
20 | 1.0
21 | 1
22 |
23 |
24 | True
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Platforms/Android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Platforms/Android/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 |
3 |
4 | [assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)]
5 | [assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)]
6 | [assembly: UsesFeature("android.hardware.location", Required = false)]
7 | [assembly: UsesFeature("android.hardware.location.gps", Required = false)]
8 | [assembly: UsesFeature("android.hardware.location.network", Required = false)]
9 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)]
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Platforms/Android/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Content.PM;
3 | using Android.OS;
4 |
5 | namespace MonkeyFinder;
6 |
7 | [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
8 | public class MainActivity : MauiAppCompatActivity
9 | {
10 | }
11 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Platforms/Android/MainApplication.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Runtime;
3 |
4 | namespace MonkeyFinder;
5 |
6 | [Application]
7 | public class MainApplication : MauiApplication
8 | {
9 | public MainApplication(IntPtr handle, JniHandleOwnership ownership)
10 | : base(handle, ownership)
11 | {
12 | }
13 |
14 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
15 | }
16 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Platforms/Android/Resources/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #512BD4
4 | #2B0B98
5 | #2B0B98
6 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Platforms/MacCatalyst/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 |
3 | namespace MonkeyFinder;
4 |
5 | [Register("AppDelegate")]
6 | public class AppDelegate : MauiUIApplicationDelegate
7 | {
8 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
9 | }
10 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Platforms/MacCatalyst/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIDeviceFamily
6 |
7 | 1
8 | 2
9 |
10 | UIRequiredDeviceCapabilities
11 |
12 | arm64
13 |
14 | UISupportedInterfaceOrientations
15 |
16 | UIInterfaceOrientationPortrait
17 | UIInterfaceOrientationLandscapeLeft
18 | UIInterfaceOrientationLandscapeRight
19 |
20 | UISupportedInterfaceOrientations~ipad
21 |
22 | UIInterfaceOrientationPortrait
23 | UIInterfaceOrientationPortraitUpsideDown
24 | UIInterfaceOrientationLandscapeLeft
25 | UIInterfaceOrientationLandscapeRight
26 |
27 | XSAppIconAssets
28 | Assets.xcassets/appicon.appiconset
29 | NSLocationWhenInUseUsageDescription
30 | Need to find monkeys!
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Platforms/MacCatalyst/Program.cs:
--------------------------------------------------------------------------------
1 | using ObjCRuntime;
2 | using UIKit;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public class Program
7 | {
8 | // This is the main entry point of the application.
9 | static void Main(string[] args)
10 | {
11 | // if you want to use a different Application Delegate class from "AppDelegate"
12 | // you can specify it here.
13 | UIApplication.Main(args, null, typeof(AppDelegate));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Platforms/Windows/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Platforms/Windows/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 |
3 | // To learn more about WinUI, the WinUI project structure,
4 | // and more about our project templates, see: http://aka.ms/winui-project-info.
5 |
6 | namespace MonkeyFinder.WinUI;
7 |
8 | ///
9 | /// Provides application-specific behavior to supplement the default Application class.
10 | ///
11 | public partial class App : MauiWinUIApplication
12 | {
13 | ///
14 | /// Initializes the singleton application object. This is the first line of authored code
15 | /// executed, and as such is the logical equivalent of main() or WinMain().
16 | ///
17 | public App()
18 | {
19 | this.InitializeComponent();
20 | }
21 |
22 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Platforms/Windows/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 | MonkeyFinder
16 | Microsoft
17 | appiconStoreLogo.png
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
39 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Platforms/Windows/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 | true/PM
12 | PerMonitorV2, PerMonitor
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Platforms/iOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 |
3 | namespace MonkeyFinder;
4 |
5 | [Register("AppDelegate")]
6 | public class AppDelegate : MauiUIApplicationDelegate
7 | {
8 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
9 | }
10 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Platforms/iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | LSRequiresIPhoneOS
6 |
7 | UIDeviceFamily
8 |
9 | 1
10 | 2
11 |
12 | UIRequiredDeviceCapabilities
13 |
14 | arm64
15 |
16 | UISupportedInterfaceOrientations
17 |
18 | UIInterfaceOrientationPortrait
19 | UIInterfaceOrientationLandscapeLeft
20 | UIInterfaceOrientationLandscapeRight
21 |
22 | UISupportedInterfaceOrientations~ipad
23 |
24 | UIInterfaceOrientationPortrait
25 | UIInterfaceOrientationPortraitUpsideDown
26 | UIInterfaceOrientationLandscapeLeft
27 | UIInterfaceOrientationLandscapeRight
28 |
29 | XSAppIconAssets
30 | Assets.xcassets/appicon.appiconset
31 | NSLocationWhenInUseUsageDescription
32 | Need to find monkeys!
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Platforms/iOS/Program.cs:
--------------------------------------------------------------------------------
1 | using ObjCRuntime;
2 | using UIKit;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public class Program
7 | {
8 | // This is the main entry point of the application.
9 | static void Main(string[] args)
10 | {
11 | // if you want to use a different Application Delegate class from "AppDelegate"
12 | // you can specify it here.
13 | UIApplication.Main(args, null, typeof(AppDelegate));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "Windows Machine": {
4 | "commandName": "MsixPackage",
5 | "nativeDebugging": false
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Resources/Fonts/OpenSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Part 1 - Displaying Data/MonkeyFinder/Resources/Fonts/OpenSans-Regular.ttf
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Resources/Images/nodata.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Part 1 - Displaying Data/MonkeyFinder/Resources/Images/nodata.png
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Resources/Raw/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories) and given a Build Action of "MauiAsset":
3 |
4 |
5 |
6 | These files will be deployed with you package and will be accessible using .NET MAUI:
7 |
8 | async Task LoadMauiAsset()
9 | {
10 | using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
11 | using var reader = new StreamReader(stream);
12 |
13 | var contents = reader.ReadToEnd();
14 | }
15 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Resources/appicon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Resources/appiconfg.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/Services/MonkeyService.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.Services;
2 |
3 | public class MonkeyService
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/View/DetailsPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/View/DetailsPage.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class DetailsPage : ContentPage
4 | {
5 | public DetailsPage()
6 | {
7 | InitializeComponent();
8 | }
9 | }
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/View/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/View/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.View;
2 |
3 | public partial class MainPage : ContentPage
4 | {
5 | public MainPage()
6 | {
7 | InitializeComponent();
8 | }
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/ViewModel/BaseViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.ViewModel;
2 |
3 | public class BaseViewModel
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/ViewModel/MonkeyDetailsViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.ViewModel;
2 |
3 | public partial class MonkeyDetailsViewModel : BaseViewModel
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/Part 1 - Displaying Data/MonkeyFinder/ViewModel/MonkeysViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.ViewModel;
2 |
3 | public partial class MonkeysViewModel : BaseViewModel
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.31611.283
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonkeyFinder", "MonkeyFinder\MonkeyFinder.csproj", "{C60F2B1C-790E-4432-A719-52182A333ADE}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{393B8F30-F402-46A9-B209-8C71897A3416}"
9 | ProjectSection(SolutionItems) = preProject
10 | ..\Directory.build.props = ..\Directory.build.props
11 | ..\Directory.build.targets = ..\Directory.build.targets
12 | README.md = README.md
13 | EndProjectSection
14 | EndProject
15 | Global
16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 | Debug|Any CPU = Debug|Any CPU
18 | Release|Any CPU = Release|Any CPU
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
24 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.Deploy.0 = Release|Any CPU
27 | EndGlobalSection
28 | GlobalSection(SolutionProperties) = preSolution
29 | HideSolutionNode = FALSE
30 | EndGlobalSection
31 | GlobalSection(ExtensibilityGlobals) = postSolution
32 | SolutionGuid = {61F7FB11-1E47-470C-91E2-47F8143E1572}
33 | EndGlobalSection
34 | EndGlobal
35 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/App.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class App : Application
4 | {
5 | public App()
6 | {
7 | InitializeComponent();
8 |
9 | MainPage = new AppShell();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/AppShell.xaml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
35 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/AppShell.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class AppShell : Shell
4 | {
5 | public AppShell()
6 | {
7 | InitializeComponent();
8 | }
9 | }
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using CommunityToolkit.Mvvm.ComponentModel;
2 | global using CommunityToolkit.Mvvm.Input;
3 | global using MonkeyFinder.Model;
4 | global using MonkeyFinder.ViewModel;
5 | global using System.Collections.ObjectModel;
6 | global using System.ComponentModel;
7 | global using System.Diagnostics;
8 | global using System.Runtime.CompilerServices;
9 | global using System.Text.Json;
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/MauiProgram.cs:
--------------------------------------------------------------------------------
1 | using MonkeyFinder.View;
2 |
3 | namespace MonkeyFinder;
4 |
5 | public static class MauiProgram
6 | {
7 | public static MauiApp CreateMauiApp()
8 | {
9 | var builder = MauiApp.CreateBuilder();
10 | builder
11 | .UseMauiApp()
12 | .ConfigureFonts(fonts =>
13 | {
14 | fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
15 | });
16 |
17 | builder.Services.AddSingleton();
18 |
19 | return builder.Build();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Model/Monkey.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.Model;
2 |
3 | public class Monkey
4 | {
5 | public string Name { get; set; }
6 | public string Location { get; set; }
7 | public string Details { get; set; }
8 | public string Image { get; set; }
9 | public int Population { get; set; }
10 | public double Latitude { get; set; }
11 | public double Longitude { get; set; }
12 | }
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/MonkeyFinder.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0-android;net6.0-ios;net6.0-maccatalyst
5 | $(TargetFrameworks);net6.0-windows10.0.19041
6 | Exe
7 | MonkeyFinder
8 | true
9 | true
10 | enable
11 |
12 |
13 | MonkeyFinder
14 |
15 |
16 | com.companyname.monkeyfinder
17 | ECD44DAE-B03E-4D8B-B427-71865961E696
18 |
19 |
20 | 1.0
21 | 1
22 |
23 |
24 | True
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Platforms/Android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Platforms/Android/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 |
3 |
4 | [assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)]
5 | [assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)]
6 | [assembly: UsesFeature("android.hardware.location", Required = false)]
7 | [assembly: UsesFeature("android.hardware.location.gps", Required = false)]
8 | [assembly: UsesFeature("android.hardware.location.network", Required = false)]
9 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)]
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Platforms/Android/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Content.PM;
3 | using Android.OS;
4 |
5 | namespace MonkeyFinder;
6 |
7 | [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
8 | public class MainActivity : MauiAppCompatActivity
9 | {
10 | }
11 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Platforms/Android/MainApplication.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Runtime;
3 |
4 | namespace MonkeyFinder;
5 |
6 | [Application]
7 | public class MainApplication : MauiApplication
8 | {
9 | public MainApplication(IntPtr handle, JniHandleOwnership ownership)
10 | : base(handle, ownership)
11 | {
12 | }
13 |
14 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
15 | }
16 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Platforms/Android/Resources/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #512BD4
4 | #2B0B98
5 | #2B0B98
6 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Platforms/MacCatalyst/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 |
3 | namespace MonkeyFinder;
4 |
5 | [Register("AppDelegate")]
6 | public class AppDelegate : MauiUIApplicationDelegate
7 | {
8 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
9 | }
10 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Platforms/MacCatalyst/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIDeviceFamily
6 |
7 | 1
8 | 2
9 |
10 | UIRequiredDeviceCapabilities
11 |
12 | arm64
13 |
14 | UISupportedInterfaceOrientations
15 |
16 | UIInterfaceOrientationPortrait
17 | UIInterfaceOrientationLandscapeLeft
18 | UIInterfaceOrientationLandscapeRight
19 |
20 | UISupportedInterfaceOrientations~ipad
21 |
22 | UIInterfaceOrientationPortrait
23 | UIInterfaceOrientationPortraitUpsideDown
24 | UIInterfaceOrientationLandscapeLeft
25 | UIInterfaceOrientationLandscapeRight
26 |
27 | XSAppIconAssets
28 | Assets.xcassets/appicon.appiconset
29 | NSLocationWhenInUseUsageDescription
30 | Need to find monkeys!
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Platforms/MacCatalyst/Program.cs:
--------------------------------------------------------------------------------
1 | using ObjCRuntime;
2 | using UIKit;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public class Program
7 | {
8 | // This is the main entry point of the application.
9 | static void Main(string[] args)
10 | {
11 | // if you want to use a different Application Delegate class from "AppDelegate"
12 | // you can specify it here.
13 | UIApplication.Main(args, null, typeof(AppDelegate));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Platforms/Windows/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Platforms/Windows/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 |
3 | // To learn more about WinUI, the WinUI project structure,
4 | // and more about our project templates, see: http://aka.ms/winui-project-info.
5 |
6 | namespace MonkeyFinder.WinUI;
7 |
8 | ///
9 | /// Provides application-specific behavior to supplement the default Application class.
10 | ///
11 | public partial class App : MauiWinUIApplication
12 | {
13 | ///
14 | /// Initializes the singleton application object. This is the first line of authored code
15 | /// executed, and as such is the logical equivalent of main() or WinMain().
16 | ///
17 | public App()
18 | {
19 | this.InitializeComponent();
20 | }
21 |
22 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Platforms/Windows/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 | MonkeyFinder
16 | Microsoft
17 | appiconStoreLogo.png
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
39 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Platforms/Windows/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 | true/PM
12 | PerMonitorV2, PerMonitor
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Platforms/iOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 |
3 | namespace MonkeyFinder;
4 |
5 | [Register("AppDelegate")]
6 | public class AppDelegate : MauiUIApplicationDelegate
7 | {
8 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
9 | }
10 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Platforms/iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | LSRequiresIPhoneOS
6 |
7 | UIDeviceFamily
8 |
9 | 1
10 | 2
11 |
12 | UIRequiredDeviceCapabilities
13 |
14 | arm64
15 |
16 | UISupportedInterfaceOrientations
17 |
18 | UIInterfaceOrientationPortrait
19 | UIInterfaceOrientationLandscapeLeft
20 | UIInterfaceOrientationLandscapeRight
21 |
22 | UISupportedInterfaceOrientations~ipad
23 |
24 | UIInterfaceOrientationPortrait
25 | UIInterfaceOrientationPortraitUpsideDown
26 | UIInterfaceOrientationLandscapeLeft
27 | UIInterfaceOrientationLandscapeRight
28 |
29 | XSAppIconAssets
30 | Assets.xcassets/appicon.appiconset
31 | NSLocationWhenInUseUsageDescription
32 | Need to find monkeys!
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Platforms/iOS/Program.cs:
--------------------------------------------------------------------------------
1 | using ObjCRuntime;
2 | using UIKit;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public class Program
7 | {
8 | // This is the main entry point of the application.
9 | static void Main(string[] args)
10 | {
11 | // if you want to use a different Application Delegate class from "AppDelegate"
12 | // you can specify it here.
13 | UIApplication.Main(args, null, typeof(AppDelegate));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "Windows Machine": {
4 | "commandName": "MsixPackage",
5 | "nativeDebugging": false
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Resources/Fonts/OpenSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Part 2 - MVVM/MonkeyFinder/Resources/Fonts/OpenSans-Regular.ttf
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Resources/Images/nodata.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Part 2 - MVVM/MonkeyFinder/Resources/Images/nodata.png
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Resources/Raw/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories) and given a Build Action of "MauiAsset":
3 |
4 |
5 |
6 | These files will be deployed with you package and will be accessible using .NET MAUI:
7 |
8 | async Task LoadMauiAsset()
9 | {
10 | using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
11 | using var reader = new StreamReader(stream);
12 |
13 | var contents = reader.ReadToEnd();
14 | }
15 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Resources/appicon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Resources/appiconfg.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/Services/MonkeyService.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.Services;
2 |
3 | public class MonkeyService
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/View/DetailsPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/View/DetailsPage.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class DetailsPage : ContentPage
4 | {
5 | public DetailsPage()
6 | {
7 | InitializeComponent();
8 | }
9 | }
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/View/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
15 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
33 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/View/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.View;
2 |
3 | public partial class MainPage : ContentPage
4 | {
5 | public MainPage()
6 | {
7 | InitializeComponent();
8 | }
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/ViewModel/BaseViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.ViewModel;
2 |
3 | public class BaseViewModel
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/ViewModel/MonkeyDetailsViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.ViewModel;
2 |
3 | public partial class MonkeyDetailsViewModel : BaseViewModel
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/Part 2 - MVVM/MonkeyFinder/ViewModel/MonkeysViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.ViewModel;
2 |
3 | public partial class MonkeysViewModel : BaseViewModel
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.31611.283
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonkeyFinder", "MonkeyFinder\MonkeyFinder.csproj", "{C60F2B1C-790E-4432-A719-52182A333ADE}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{393B8F30-F402-46A9-B209-8C71897A3416}"
9 | ProjectSection(SolutionItems) = preProject
10 | ..\Directory.build.props = ..\Directory.build.props
11 | ..\Directory.build.targets = ..\Directory.build.targets
12 | README.md = README.md
13 | EndProjectSection
14 | EndProject
15 | Global
16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 | Debug|Any CPU = Debug|Any CPU
18 | Release|Any CPU = Release|Any CPU
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
24 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.Deploy.0 = Release|Any CPU
27 | EndGlobalSection
28 | GlobalSection(SolutionProperties) = preSolution
29 | HideSolutionNode = FALSE
30 | EndGlobalSection
31 | GlobalSection(ExtensibilityGlobals) = postSolution
32 | SolutionGuid = {61F7FB11-1E47-470C-91E2-47F8143E1572}
33 | EndGlobalSection
34 | EndGlobal
35 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/App.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class App : Application
4 | {
5 | public App()
6 | {
7 | InitializeComponent();
8 |
9 | MainPage = new AppShell();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/AppShell.xaml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
35 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/AppShell.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class AppShell : Shell
4 | {
5 | public AppShell()
6 | {
7 | InitializeComponent();
8 | }
9 | }
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using CommunityToolkit.Mvvm.ComponentModel;
2 | global using CommunityToolkit.Mvvm.Input;
3 | global using MonkeyFinder.Model;
4 | global using MonkeyFinder.ViewModel;
5 | global using System.Collections.ObjectModel;
6 | global using System.ComponentModel;
7 | global using System.Diagnostics;
8 | global using System.Runtime.CompilerServices;
9 | global using System.Text.Json;
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/MauiProgram.cs:
--------------------------------------------------------------------------------
1 | using MonkeyFinder.Services;
2 | using MonkeyFinder.View;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public static class MauiProgram
7 | {
8 | public static MauiApp CreateMauiApp()
9 | {
10 | var builder = MauiApp.CreateBuilder();
11 | builder
12 | .UseMauiApp()
13 | .ConfigureFonts(fonts =>
14 | {
15 | fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
16 | });
17 |
18 | builder.Services.AddSingleton();
19 | builder.Services.AddSingleton();
20 | builder.Services.AddSingleton();
21 |
22 | return builder.Build();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Model/Monkey.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.Model;
2 |
3 | public class Monkey
4 | {
5 | public string Name { get; set; }
6 | public string Location { get; set; }
7 | public string Details { get; set; }
8 | public string Image { get; set; }
9 | public int Population { get; set; }
10 | public double Latitude { get; set; }
11 | public double Longitude { get; set; }
12 | }
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/MonkeyFinder.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0-android;net6.0-ios;net6.0-maccatalyst
5 | $(TargetFrameworks);net6.0-windows10.0.19041
6 | Exe
7 | MonkeyFinder
8 | true
9 | true
10 | enable
11 |
12 |
13 | MonkeyFinder
14 |
15 |
16 | com.companyname.monkeyfinder
17 | ECD44DAE-B03E-4D8B-B427-71865961E696
18 |
19 |
20 | 1.0
21 | 1
22 |
23 |
24 | True
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Platforms/Android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Platforms/Android/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 |
3 |
4 | [assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)]
5 | [assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)]
6 | [assembly: UsesFeature("android.hardware.location", Required = false)]
7 | [assembly: UsesFeature("android.hardware.location.gps", Required = false)]
8 | [assembly: UsesFeature("android.hardware.location.network", Required = false)]
9 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)]
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Platforms/Android/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Content.PM;
3 | using Android.OS;
4 |
5 | namespace MonkeyFinder;
6 |
7 | [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
8 | public class MainActivity : MauiAppCompatActivity
9 | {
10 | }
11 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Platforms/Android/MainApplication.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Runtime;
3 |
4 | namespace MonkeyFinder;
5 |
6 | [Application]
7 | public class MainApplication : MauiApplication
8 | {
9 | public MainApplication(IntPtr handle, JniHandleOwnership ownership)
10 | : base(handle, ownership)
11 | {
12 | }
13 |
14 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
15 | }
16 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Platforms/Android/Resources/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #512BD4
4 | #2B0B98
5 | #2B0B98
6 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Platforms/MacCatalyst/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 |
3 | namespace MonkeyFinder;
4 |
5 | [Register("AppDelegate")]
6 | public class AppDelegate : MauiUIApplicationDelegate
7 | {
8 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
9 | }
10 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Platforms/MacCatalyst/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIDeviceFamily
6 |
7 | 1
8 | 2
9 |
10 | UIRequiredDeviceCapabilities
11 |
12 | arm64
13 |
14 | UISupportedInterfaceOrientations
15 |
16 | UIInterfaceOrientationPortrait
17 | UIInterfaceOrientationLandscapeLeft
18 | UIInterfaceOrientationLandscapeRight
19 |
20 | UISupportedInterfaceOrientations~ipad
21 |
22 | UIInterfaceOrientationPortrait
23 | UIInterfaceOrientationPortraitUpsideDown
24 | UIInterfaceOrientationLandscapeLeft
25 | UIInterfaceOrientationLandscapeRight
26 |
27 | XSAppIconAssets
28 | Assets.xcassets/appicon.appiconset
29 | NSLocationWhenInUseUsageDescription
30 | Need to find monkeys!
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Platforms/MacCatalyst/Program.cs:
--------------------------------------------------------------------------------
1 | using ObjCRuntime;
2 | using UIKit;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public class Program
7 | {
8 | // This is the main entry point of the application.
9 | static void Main(string[] args)
10 | {
11 | // if you want to use a different Application Delegate class from "AppDelegate"
12 | // you can specify it here.
13 | UIApplication.Main(args, null, typeof(AppDelegate));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Platforms/Windows/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Platforms/Windows/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 |
3 | // To learn more about WinUI, the WinUI project structure,
4 | // and more about our project templates, see: http://aka.ms/winui-project-info.
5 |
6 | namespace MonkeyFinder.WinUI;
7 |
8 | ///
9 | /// Provides application-specific behavior to supplement the default Application class.
10 | ///
11 | public partial class App : MauiWinUIApplication
12 | {
13 | ///
14 | /// Initializes the singleton application object. This is the first line of authored code
15 | /// executed, and as such is the logical equivalent of main() or WinMain().
16 | ///
17 | public App()
18 | {
19 | this.InitializeComponent();
20 | }
21 |
22 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Platforms/Windows/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 | MonkeyFinder
16 | Microsoft
17 | appiconStoreLogo.png
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
39 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Platforms/Windows/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 | true/PM
12 | PerMonitorV2, PerMonitor
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Platforms/iOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 |
3 | namespace MonkeyFinder;
4 |
5 | [Register("AppDelegate")]
6 | public class AppDelegate : MauiUIApplicationDelegate
7 | {
8 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
9 | }
10 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Platforms/iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | LSRequiresIPhoneOS
6 |
7 | UIDeviceFamily
8 |
9 | 1
10 | 2
11 |
12 | UIRequiredDeviceCapabilities
13 |
14 | arm64
15 |
16 | UISupportedInterfaceOrientations
17 |
18 | UIInterfaceOrientationPortrait
19 | UIInterfaceOrientationLandscapeLeft
20 | UIInterfaceOrientationLandscapeRight
21 |
22 | UISupportedInterfaceOrientations~ipad
23 |
24 | UIInterfaceOrientationPortrait
25 | UIInterfaceOrientationPortraitUpsideDown
26 | UIInterfaceOrientationLandscapeLeft
27 | UIInterfaceOrientationLandscapeRight
28 |
29 | XSAppIconAssets
30 | Assets.xcassets/appicon.appiconset
31 | NSLocationWhenInUseUsageDescription
32 | Need to find monkeys!
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Platforms/iOS/Program.cs:
--------------------------------------------------------------------------------
1 | using ObjCRuntime;
2 | using UIKit;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public class Program
7 | {
8 | // This is the main entry point of the application.
9 | static void Main(string[] args)
10 | {
11 | // if you want to use a different Application Delegate class from "AppDelegate"
12 | // you can specify it here.
13 | UIApplication.Main(args, null, typeof(AppDelegate));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "Windows Machine": {
4 | "commandName": "MsixPackage",
5 | "nativeDebugging": false
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Resources/Fonts/OpenSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Part 3 - Navigation/MonkeyFinder/Resources/Fonts/OpenSans-Regular.ttf
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Resources/Images/nodata.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Part 3 - Navigation/MonkeyFinder/Resources/Images/nodata.png
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Resources/Raw/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories) and given a Build Action of "MauiAsset":
3 |
4 |
5 |
6 | These files will be deployed with you package and will be accessible using .NET MAUI:
7 |
8 | async Task LoadMauiAsset()
9 | {
10 | using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
11 | using var reader = new StreamReader(stream);
12 |
13 | var contents = reader.ReadToEnd();
14 | }
15 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Resources/appicon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Resources/appiconfg.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/Services/MonkeyService.cs:
--------------------------------------------------------------------------------
1 | using System.Net.Http.Json;
2 |
3 | namespace MonkeyFinder.Services;
4 |
5 | public class MonkeyService
6 | {
7 | HttpClient httpClient;
8 | public MonkeyService()
9 | {
10 | this.httpClient = new HttpClient();
11 | }
12 |
13 | List monkeyList;
14 | public async Task> GetMonkeys()
15 | {
16 | if (monkeyList?.Count > 0)
17 | return monkeyList;
18 |
19 | // Online
20 | var response = await httpClient.GetAsync("https://www.montemagno.com/monkeys.json");
21 | if (response.IsSuccessStatusCode)
22 | {
23 | monkeyList = await response.Content.ReadFromJsonAsync>();
24 | }
25 |
26 | // Offline
27 | /*using var stream = await FileSystem.OpenAppPackageFileAsync("monkeydata.json");
28 | using var reader = new StreamReader(stream);
29 | var contents = await reader.ReadToEndAsync();
30 | monkeyList = JsonSerializer.Deserialize>(contents);*/
31 |
32 | return monkeyList;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/View/DetailsPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/View/DetailsPage.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class DetailsPage : ContentPage
4 | {
5 | public DetailsPage()
6 | {
7 | InitializeComponent();
8 | }
9 | }
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/View/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.View;
2 |
3 | public partial class MainPage : ContentPage
4 | {
5 | public MainPage(MonkeysViewModel viewModel)
6 | {
7 | InitializeComponent();
8 | BindingContext = viewModel;
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/ViewModel/BaseViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.ViewModel;
2 |
3 | public partial class BaseViewModel : ObservableObject
4 | {
5 | [ObservableProperty]
6 | [NotifyPropertyChangedFor(nameof(IsNotBusy))]
7 | bool isBusy;
8 |
9 | [ObservableProperty]
10 | string title;
11 |
12 | public bool IsNotBusy => !IsBusy;
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/ViewModel/MonkeyDetailsViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.ViewModel;
2 |
3 | public class MonkeyDetailsViewModel : BaseViewModel
4 | {
5 | }
6 |
--------------------------------------------------------------------------------
/Part 3 - Navigation/MonkeyFinder/ViewModel/MonkeysViewModel.cs:
--------------------------------------------------------------------------------
1 | using MonkeyFinder.Services;
2 |
3 | namespace MonkeyFinder.ViewModel;
4 |
5 | public partial class MonkeysViewModel : BaseViewModel
6 | {
7 | public ObservableCollection Monkeys { get; } = new();
8 | MonkeyService monkeyService;
9 | public MonkeysViewModel(MonkeyService monkeyService)
10 | {
11 | Title = "Monkey Finder";
12 | this.monkeyService = monkeyService;
13 | }
14 |
15 | [RelayCommand]
16 | async Task GetMonkeysAsync()
17 | {
18 | if (IsBusy)
19 | return;
20 |
21 | try
22 | {
23 | IsBusy = true;
24 | var monkeys = await monkeyService.GetMonkeys();
25 |
26 | if(Monkeys.Count != 0)
27 | Monkeys.Clear();
28 |
29 | foreach(var monkey in monkeys)
30 | Monkeys.Add(monkey);
31 |
32 | }
33 | catch (Exception ex)
34 | {
35 | Debug.WriteLine($"Unable to get monkeys: {ex.Message}");
36 | await Shell.Current.DisplayAlert("Error!", ex.Message, "OK");
37 | }
38 | finally
39 | {
40 | IsBusy = false;
41 | }
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.31611.283
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonkeyFinder", "MonkeyFinder\MonkeyFinder.csproj", "{C60F2B1C-790E-4432-A719-52182A333ADE}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{393B8F30-F402-46A9-B209-8C71897A3416}"
9 | ProjectSection(SolutionItems) = preProject
10 | ..\Directory.build.props = ..\Directory.build.props
11 | ..\Directory.build.targets = ..\Directory.build.targets
12 | README.md = README.md
13 | EndProjectSection
14 | EndProject
15 | Global
16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 | Debug|Any CPU = Debug|Any CPU
18 | Release|Any CPU = Release|Any CPU
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
24 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.Deploy.0 = Release|Any CPU
27 | EndGlobalSection
28 | GlobalSection(SolutionProperties) = preSolution
29 | HideSolutionNode = FALSE
30 | EndGlobalSection
31 | GlobalSection(ExtensibilityGlobals) = postSolution
32 | SolutionGuid = {61F7FB11-1E47-470C-91E2-47F8143E1572}
33 | EndGlobalSection
34 | EndGlobal
35 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/App.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class App : Application
4 | {
5 | public App()
6 | {
7 | InitializeComponent();
8 |
9 | MainPage = new AppShell();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/AppShell.xaml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
35 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/AppShell.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class AppShell : Shell
4 | {
5 | public AppShell()
6 | {
7 | InitializeComponent();
8 |
9 | Routing.RegisterRoute(nameof(DetailsPage), typeof(DetailsPage));
10 | }
11 | }
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using CommunityToolkit.Mvvm.ComponentModel;
2 | global using CommunityToolkit.Mvvm.Input;
3 | global using MonkeyFinder.Model;
4 | global using MonkeyFinder.ViewModel;
5 | global using System.Collections.ObjectModel;
6 | global using System.ComponentModel;
7 | global using System.Diagnostics;
8 | global using System.Runtime.CompilerServices;
9 | global using System.Text.Json;
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/MauiProgram.cs:
--------------------------------------------------------------------------------
1 | using MonkeyFinder.Services;
2 | using MonkeyFinder.View;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public static class MauiProgram
7 | {
8 | public static MauiApp CreateMauiApp()
9 | {
10 | var builder = MauiApp.CreateBuilder();
11 | builder
12 | .UseMauiApp()
13 | .ConfigureFonts(fonts =>
14 | {
15 | fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
16 | });
17 |
18 | builder.Services.AddSingleton();
19 | builder.Services.AddSingleton();
20 | builder.Services.AddSingleton();
21 |
22 | builder.Services.AddTransient();
23 | builder.Services.AddTransient();
24 |
25 | return builder.Build();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Model/Monkey.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.Model;
2 |
3 | public class Monkey
4 | {
5 | public string Name { get; set; }
6 | public string Location { get; set; }
7 | public string Details { get; set; }
8 | public string Image { get; set; }
9 | public int Population { get; set; }
10 | public double Latitude { get; set; }
11 | public double Longitude { get; set; }
12 | }
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/MonkeyFinder.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0-android;net6.0-ios;net6.0-maccatalyst
5 | $(TargetFrameworks);net6.0-windows10.0.19041
6 | Exe
7 | MonkeyFinder
8 | true
9 | true
10 | enable
11 |
12 |
13 | MonkeyFinder
14 |
15 |
16 | com.companyname.monkeyfinder
17 | ECD44DAE-B03E-4D8B-B427-71865961E696
18 |
19 |
20 | 1.0
21 | 1
22 |
23 |
24 | True
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Platforms/Android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Platforms/Android/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 |
3 |
4 | [assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)]
5 | [assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)]
6 | [assembly: UsesFeature("android.hardware.location", Required = false)]
7 | [assembly: UsesFeature("android.hardware.location.gps", Required = false)]
8 | [assembly: UsesFeature("android.hardware.location.network", Required = false)]
9 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)]
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Platforms/Android/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Content.PM;
3 | using Android.OS;
4 |
5 | namespace MonkeyFinder;
6 |
7 | [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
8 | public class MainActivity : MauiAppCompatActivity
9 | {
10 | }
11 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Platforms/Android/MainApplication.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Runtime;
3 |
4 | namespace MonkeyFinder;
5 |
6 | [Application]
7 | public class MainApplication : MauiApplication
8 | {
9 | public MainApplication(IntPtr handle, JniHandleOwnership ownership)
10 | : base(handle, ownership)
11 | {
12 | }
13 |
14 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
15 | }
16 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Platforms/Android/Resources/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #512BD4
4 | #2B0B98
5 | #2B0B98
6 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Platforms/MacCatalyst/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 |
3 | namespace MonkeyFinder;
4 |
5 | [Register("AppDelegate")]
6 | public class AppDelegate : MauiUIApplicationDelegate
7 | {
8 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
9 | }
10 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Platforms/MacCatalyst/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIDeviceFamily
6 |
7 | 1
8 | 2
9 |
10 | UIRequiredDeviceCapabilities
11 |
12 | arm64
13 |
14 | UISupportedInterfaceOrientations
15 |
16 | UIInterfaceOrientationPortrait
17 | UIInterfaceOrientationLandscapeLeft
18 | UIInterfaceOrientationLandscapeRight
19 |
20 | UISupportedInterfaceOrientations~ipad
21 |
22 | UIInterfaceOrientationPortrait
23 | UIInterfaceOrientationPortraitUpsideDown
24 | UIInterfaceOrientationLandscapeLeft
25 | UIInterfaceOrientationLandscapeRight
26 |
27 | XSAppIconAssets
28 | Assets.xcassets/appicon.appiconset
29 | NSLocationWhenInUseUsageDescription
30 | Need to find monkeys!
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Platforms/MacCatalyst/Program.cs:
--------------------------------------------------------------------------------
1 | using ObjCRuntime;
2 | using UIKit;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public class Program
7 | {
8 | // This is the main entry point of the application.
9 | static void Main(string[] args)
10 | {
11 | // if you want to use a different Application Delegate class from "AppDelegate"
12 | // you can specify it here.
13 | UIApplication.Main(args, null, typeof(AppDelegate));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Platforms/Windows/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Platforms/Windows/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 |
3 | // To learn more about WinUI, the WinUI project structure,
4 | // and more about our project templates, see: http://aka.ms/winui-project-info.
5 |
6 | namespace MonkeyFinder.WinUI;
7 |
8 | ///
9 | /// Provides application-specific behavior to supplement the default Application class.
10 | ///
11 | public partial class App : MauiWinUIApplication
12 | {
13 | ///
14 | /// Initializes the singleton application object. This is the first line of authored code
15 | /// executed, and as such is the logical equivalent of main() or WinMain().
16 | ///
17 | public App()
18 | {
19 | this.InitializeComponent();
20 | }
21 |
22 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Platforms/Windows/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 | MonkeyFinder
16 | Microsoft
17 | appiconStoreLogo.png
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
39 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Platforms/Windows/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 | true/PM
12 | PerMonitorV2, PerMonitor
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Platforms/iOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 |
3 | namespace MonkeyFinder;
4 |
5 | [Register("AppDelegate")]
6 | public class AppDelegate : MauiUIApplicationDelegate
7 | {
8 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
9 | }
10 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Platforms/iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | LSRequiresIPhoneOS
6 |
7 | UIDeviceFamily
8 |
9 | 1
10 | 2
11 |
12 | UIRequiredDeviceCapabilities
13 |
14 | arm64
15 |
16 | UISupportedInterfaceOrientations
17 |
18 | UIInterfaceOrientationPortrait
19 | UIInterfaceOrientationLandscapeLeft
20 | UIInterfaceOrientationLandscapeRight
21 |
22 | UISupportedInterfaceOrientations~ipad
23 |
24 | UIInterfaceOrientationPortrait
25 | UIInterfaceOrientationPortraitUpsideDown
26 | UIInterfaceOrientationLandscapeLeft
27 | UIInterfaceOrientationLandscapeRight
28 |
29 | XSAppIconAssets
30 | Assets.xcassets/appicon.appiconset
31 | NSLocationWhenInUseUsageDescription
32 | Need to find monkeys!
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Platforms/iOS/Program.cs:
--------------------------------------------------------------------------------
1 | using ObjCRuntime;
2 | using UIKit;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public class Program
7 | {
8 | // This is the main entry point of the application.
9 | static void Main(string[] args)
10 | {
11 | // if you want to use a different Application Delegate class from "AppDelegate"
12 | // you can specify it here.
13 | UIApplication.Main(args, null, typeof(AppDelegate));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "Windows Machine": {
4 | "commandName": "MsixPackage",
5 | "nativeDebugging": false
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Resources/Fonts/OpenSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Part 4 - Platform Features/MonkeyFinder/Resources/Fonts/OpenSans-Regular.ttf
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Resources/Images/nodata.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Part 4 - Platform Features/MonkeyFinder/Resources/Images/nodata.png
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Resources/Raw/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories) and given a Build Action of "MauiAsset":
3 |
4 |
5 |
6 | These files will be deployed with you package and will be accessible using .NET MAUI:
7 |
8 | async Task LoadMauiAsset()
9 | {
10 | using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
11 | using var reader = new StreamReader(stream);
12 |
13 | var contents = reader.ReadToEnd();
14 | }
15 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Resources/appicon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Resources/appiconfg.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/Services/MonkeyService.cs:
--------------------------------------------------------------------------------
1 | using System.Net.Http.Json;
2 |
3 | namespace MonkeyFinder.Services;
4 |
5 | public class MonkeyService
6 | {
7 | HttpClient httpClient;
8 | public MonkeyService()
9 | {
10 | this.httpClient = new HttpClient();
11 | }
12 |
13 | List monkeyList;
14 | public async Task> GetMonkeys()
15 | {
16 | if (monkeyList?.Count > 0)
17 | return monkeyList;
18 |
19 | // Online
20 | /*var response = await httpClient.GetAsync("https://www.montemagno.com/monkeys.json");
21 | if (response.IsSuccessStatusCode)
22 | {
23 | monkeyList = await response.Content.ReadFromJsonAsync>();
24 | }*/
25 |
26 | // Offline
27 | using var stream = await FileSystem.OpenAppPackageFileAsync("monkeydata.json");
28 | using var reader = new StreamReader(stream);
29 | var contents = await reader.ReadToEndAsync();
30 | monkeyList = JsonSerializer.Deserialize>(contents);
31 |
32 | return monkeyList;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/View/DetailsPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
17 |
27 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/View/DetailsPage.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class DetailsPage : ContentPage
4 | {
5 | public DetailsPage(MonkeyDetailsViewModel viewModel)
6 | {
7 | InitializeComponent();
8 | BindingContext = viewModel;
9 | }
10 | }
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/View/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.View;
2 |
3 | public partial class MainPage : ContentPage
4 | {
5 | public MainPage(MonkeysViewModel viewModel)
6 | {
7 | InitializeComponent();
8 | BindingContext = viewModel;
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/ViewModel/BaseViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.ViewModel;
2 |
3 | public partial class BaseViewModel : ObservableObject
4 | {
5 | [ObservableProperty]
6 | [NotifyPropertyChangedFor(nameof(IsNotBusy))]
7 | bool isBusy;
8 |
9 | [ObservableProperty]
10 | string title;
11 |
12 | public bool IsNotBusy => !IsBusy;
13 | }
14 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/ViewModel/MonkeyDetailsViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.ViewModel;
2 |
3 | [QueryProperty(nameof(Monkey), "Monkey")]
4 | public partial class MonkeyDetailsViewModel : BaseViewModel
5 | {
6 | public MonkeyDetailsViewModel()
7 | {
8 | }
9 |
10 | [ObservableProperty]
11 | Monkey monkey;
12 | }
13 |
--------------------------------------------------------------------------------
/Part 4 - Platform Features/MonkeyFinder/ViewModel/MonkeysViewModel.cs:
--------------------------------------------------------------------------------
1 | using MonkeyFinder.Services;
2 |
3 | namespace MonkeyFinder.ViewModel;
4 |
5 | public partial class MonkeysViewModel : BaseViewModel
6 | {
7 | public ObservableCollection Monkeys { get; } = new();
8 | MonkeyService monkeyService;
9 | public MonkeysViewModel(MonkeyService monkeyService)
10 | {
11 | Title = "Monkey Finder";
12 | this.monkeyService = monkeyService;
13 | }
14 |
15 | [RelayCommand]
16 | async Task GoToDetails(Monkey monkey)
17 | {
18 | if (monkey == null)
19 | return;
20 |
21 | await Shell.Current.GoToAsync(nameof(DetailsPage), true, new Dictionary
22 | {
23 | {"Monkey", monkey }
24 | });
25 | }
26 |
27 | [RelayCommand]
28 | async Task GetMonkeysAsync()
29 | {
30 | if (IsBusy)
31 | return;
32 |
33 | try
34 | {
35 | IsBusy = true;
36 | var monkeys = await monkeyService.GetMonkeys();
37 |
38 | if(Monkeys.Count != 0)
39 | Monkeys.Clear();
40 |
41 | foreach(var monkey in monkeys)
42 | Monkeys.Add(monkey);
43 |
44 | }
45 | catch (Exception ex)
46 | {
47 | Debug.WriteLine($"Unable to get monkeys: {ex.Message}");
48 | await Shell.Current.DisplayAlert("Error!", ex.Message, "OK");
49 | }
50 | finally
51 | {
52 | IsBusy = false;
53 | }
54 |
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.31611.283
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonkeyFinder", "MonkeyFinder\MonkeyFinder.csproj", "{C60F2B1C-790E-4432-A719-52182A333ADE}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{393B8F30-F402-46A9-B209-8C71897A3416}"
9 | ProjectSection(SolutionItems) = preProject
10 | ..\Directory.build.props = ..\Directory.build.props
11 | ..\Directory.build.targets = ..\Directory.build.targets
12 | README.md = README.md
13 | EndProjectSection
14 | EndProject
15 | Global
16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 | Debug|Any CPU = Debug|Any CPU
18 | Release|Any CPU = Release|Any CPU
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
24 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.Deploy.0 = Release|Any CPU
27 | EndGlobalSection
28 | GlobalSection(SolutionProperties) = preSolution
29 | HideSolutionNode = FALSE
30 | EndGlobalSection
31 | GlobalSection(ExtensibilityGlobals) = postSolution
32 | SolutionGuid = {61F7FB11-1E47-470C-91E2-47F8143E1572}
33 | EndGlobalSection
34 | EndGlobal
35 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/App.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class App : Application
4 | {
5 | public App()
6 | {
7 | InitializeComponent();
8 |
9 | MainPage = new AppShell();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/AppShell.xaml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
35 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/AppShell.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class AppShell : Shell
4 | {
5 | public AppShell()
6 | {
7 | InitializeComponent();
8 |
9 | Routing.RegisterRoute(nameof(DetailsPage), typeof(DetailsPage));
10 | }
11 | }
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using CommunityToolkit.Mvvm.ComponentModel;
2 | global using CommunityToolkit.Mvvm.Input;
3 | global using MonkeyFinder.Model;
4 | global using MonkeyFinder.ViewModel;
5 | global using System.Collections.ObjectModel;
6 | global using System.ComponentModel;
7 | global using System.Diagnostics;
8 | global using System.Runtime.CompilerServices;
9 | global using System.Text.Json;
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/MauiProgram.cs:
--------------------------------------------------------------------------------
1 | using MonkeyFinder.Services;
2 | using MonkeyFinder.View;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public static class MauiProgram
7 | {
8 | public static MauiApp CreateMauiApp()
9 | {
10 | var builder = MauiApp.CreateBuilder();
11 | builder
12 | .UseMauiApp()
13 | .ConfigureFonts(fonts =>
14 | {
15 | fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
16 | });
17 |
18 | builder.Services.AddSingleton(Connectivity.Current);
19 | builder.Services.AddSingleton(Geolocation.Default);
20 | builder.Services.AddSingleton(Map.Default);
21 |
22 | builder.Services.AddSingleton();
23 | builder.Services.AddSingleton();
24 | builder.Services.AddSingleton();
25 |
26 | builder.Services.AddTransient();
27 | builder.Services.AddTransient();
28 |
29 | return builder.Build();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Model/Monkey.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.Model;
2 |
3 | public class Monkey
4 | {
5 | public string Name { get; set; }
6 | public string Location { get; set; }
7 | public string Details { get; set; }
8 | public string Image { get; set; }
9 | public int Population { get; set; }
10 | public double Latitude { get; set; }
11 | public double Longitude { get; set; }
12 | }
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/MonkeyFinder.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0-android;net6.0-ios;net6.0-maccatalyst
5 | $(TargetFrameworks);net6.0-windows10.0.19041
6 | Exe
7 | MonkeyFinder
8 | true
9 | true
10 | enable
11 |
12 |
13 | MonkeyFinder
14 |
15 |
16 | com.companyname.monkeyfinder
17 | ECD44DAE-B03E-4D8B-B427-71865961E696
18 |
19 |
20 | 1.0
21 | 1
22 |
23 |
24 | True
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Platforms/Android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Platforms/Android/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 |
3 |
4 | [assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)]
5 | [assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)]
6 | [assembly: UsesFeature("android.hardware.location", Required = false)]
7 | [assembly: UsesFeature("android.hardware.location.gps", Required = false)]
8 | [assembly: UsesFeature("android.hardware.location.network", Required = false)]
9 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)]
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Platforms/Android/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Content.PM;
3 | using Android.OS;
4 |
5 | namespace MonkeyFinder;
6 |
7 | [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
8 | public class MainActivity : MauiAppCompatActivity
9 | {
10 | }
11 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Platforms/Android/MainApplication.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Runtime;
3 |
4 | namespace MonkeyFinder;
5 |
6 | [Application]
7 | public class MainApplication : MauiApplication
8 | {
9 | public MainApplication(IntPtr handle, JniHandleOwnership ownership)
10 | : base(handle, ownership)
11 | {
12 | }
13 |
14 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
15 | }
16 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Platforms/Android/Resources/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #512BD4
4 | #2B0B98
5 | #2B0B98
6 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Platforms/MacCatalyst/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 |
3 | namespace MonkeyFinder;
4 |
5 | [Register("AppDelegate")]
6 | public class AppDelegate : MauiUIApplicationDelegate
7 | {
8 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
9 | }
10 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Platforms/MacCatalyst/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIDeviceFamily
6 |
7 | 1
8 | 2
9 |
10 | UIRequiredDeviceCapabilities
11 |
12 | arm64
13 |
14 | UISupportedInterfaceOrientations
15 |
16 | UIInterfaceOrientationPortrait
17 | UIInterfaceOrientationLandscapeLeft
18 | UIInterfaceOrientationLandscapeRight
19 |
20 | UISupportedInterfaceOrientations~ipad
21 |
22 | UIInterfaceOrientationPortrait
23 | UIInterfaceOrientationPortraitUpsideDown
24 | UIInterfaceOrientationLandscapeLeft
25 | UIInterfaceOrientationLandscapeRight
26 |
27 | XSAppIconAssets
28 | Assets.xcassets/appicon.appiconset
29 | NSLocationWhenInUseUsageDescription
30 | Need to find monkeys!
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Platforms/MacCatalyst/Program.cs:
--------------------------------------------------------------------------------
1 | using ObjCRuntime;
2 | using UIKit;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public class Program
7 | {
8 | // This is the main entry point of the application.
9 | static void Main(string[] args)
10 | {
11 | // if you want to use a different Application Delegate class from "AppDelegate"
12 | // you can specify it here.
13 | UIApplication.Main(args, null, typeof(AppDelegate));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Platforms/Windows/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Platforms/Windows/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 |
3 | // To learn more about WinUI, the WinUI project structure,
4 | // and more about our project templates, see: http://aka.ms/winui-project-info.
5 |
6 | namespace MonkeyFinder.WinUI;
7 |
8 | ///
9 | /// Provides application-specific behavior to supplement the default Application class.
10 | ///
11 | public partial class App : MauiWinUIApplication
12 | {
13 | ///
14 | /// Initializes the singleton application object. This is the first line of authored code
15 | /// executed, and as such is the logical equivalent of main() or WinMain().
16 | ///
17 | public App()
18 | {
19 | this.InitializeComponent();
20 | }
21 |
22 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Platforms/Windows/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 | MonkeyFinder
16 | Microsoft
17 | appiconStoreLogo.png
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
39 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Platforms/Windows/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 | true/PM
12 | PerMonitorV2, PerMonitor
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Platforms/iOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 |
3 | namespace MonkeyFinder;
4 |
5 | [Register("AppDelegate")]
6 | public class AppDelegate : MauiUIApplicationDelegate
7 | {
8 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
9 | }
10 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Platforms/iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | LSRequiresIPhoneOS
6 |
7 | UIDeviceFamily
8 |
9 | 1
10 | 2
11 |
12 | UIRequiredDeviceCapabilities
13 |
14 | arm64
15 |
16 | UISupportedInterfaceOrientations
17 |
18 | UIInterfaceOrientationPortrait
19 | UIInterfaceOrientationLandscapeLeft
20 | UIInterfaceOrientationLandscapeRight
21 |
22 | UISupportedInterfaceOrientations~ipad
23 |
24 | UIInterfaceOrientationPortrait
25 | UIInterfaceOrientationPortraitUpsideDown
26 | UIInterfaceOrientationLandscapeLeft
27 | UIInterfaceOrientationLandscapeRight
28 |
29 | XSAppIconAssets
30 | Assets.xcassets/appicon.appiconset
31 | NSLocationWhenInUseUsageDescription
32 | Need to find monkeys!
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Platforms/iOS/Program.cs:
--------------------------------------------------------------------------------
1 | using ObjCRuntime;
2 | using UIKit;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public class Program
7 | {
8 | // This is the main entry point of the application.
9 | static void Main(string[] args)
10 | {
11 | // if you want to use a different Application Delegate class from "AppDelegate"
12 | // you can specify it here.
13 | UIApplication.Main(args, null, typeof(AppDelegate));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "Windows Machine": {
4 | "commandName": "MsixPackage",
5 | "nativeDebugging": false
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Resources/Fonts/OpenSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Part 5 - CollectionView/MonkeyFinder/Resources/Fonts/OpenSans-Regular.ttf
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Resources/Images/nodata.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Part 5 - CollectionView/MonkeyFinder/Resources/Images/nodata.png
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Resources/Raw/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories) and given a Build Action of "MauiAsset":
3 |
4 |
5 |
6 | These files will be deployed with you package and will be accessible using .NET MAUI:
7 |
8 | async Task LoadMauiAsset()
9 | {
10 | using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
11 | using var reader = new StreamReader(stream);
12 |
13 | var contents = reader.ReadToEnd();
14 | }
15 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Resources/appicon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Resources/appiconfg.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/Services/MonkeyService.cs:
--------------------------------------------------------------------------------
1 | using System.Net.Http.Json;
2 |
3 | namespace MonkeyFinder.Services;
4 |
5 | public class MonkeyService
6 | {
7 | HttpClient httpClient;
8 | public MonkeyService()
9 | {
10 | this.httpClient = new HttpClient();
11 | }
12 |
13 | List monkeyList;
14 | public async Task> GetMonkeys()
15 | {
16 | if (monkeyList?.Count > 0)
17 | return monkeyList;
18 |
19 | // Online
20 | /*var response = await httpClient.GetAsync("https://www.montemagno.com/monkeys.json");
21 | if (response.IsSuccessStatusCode)
22 | {
23 | monkeyList = await response.Content.ReadFromJsonAsync>();
24 | }*/
25 |
26 | // Offline
27 | using var stream = await FileSystem.OpenAppPackageFileAsync("monkeydata.json");
28 | using var reader = new StreamReader(stream);
29 | var contents = await reader.ReadToEndAsync();
30 | monkeyList = JsonSerializer.Deserialize>(contents);
31 |
32 | return monkeyList;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/View/DetailsPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
17 |
27 |
34 |
35 |
36 |
37 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/View/DetailsPage.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class DetailsPage : ContentPage
4 | {
5 | public DetailsPage(MonkeyDetailsViewModel viewModel)
6 | {
7 | InitializeComponent();
8 | BindingContext = viewModel;
9 | }
10 | }
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/View/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.View;
2 |
3 | public partial class MainPage : ContentPage
4 | {
5 | public MainPage(MonkeysViewModel viewModel)
6 | {
7 | InitializeComponent();
8 | BindingContext = viewModel;
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/ViewModel/BaseViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.ViewModel;
2 |
3 | public partial class BaseViewModel : ObservableObject
4 | {
5 | [ObservableProperty]
6 | [NotifyPropertyChangedFor(nameof(IsNotBusy))]
7 | bool isBusy;
8 |
9 | [ObservableProperty]
10 | string title;
11 |
12 | public bool IsNotBusy => !IsBusy;
13 | }
14 |
--------------------------------------------------------------------------------
/Part 5 - CollectionView/MonkeyFinder/ViewModel/MonkeyDetailsViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.ViewModel;
2 |
3 | [QueryProperty(nameof(Monkey), "Monkey")]
4 | public partial class MonkeyDetailsViewModel : BaseViewModel
5 | {
6 | IMap map;
7 | public MonkeyDetailsViewModel(IMap map)
8 | {
9 | this.map = map;
10 | }
11 |
12 | [ObservableProperty]
13 | Monkey monkey;
14 |
15 | [RelayCommand]
16 | async Task OpenMap()
17 | {
18 | try
19 | {
20 | await map.OpenAsync(Monkey.Latitude, Monkey.Longitude, new MapLaunchOptions
21 | {
22 | Name = Monkey.Name,
23 | NavigationMode = NavigationMode.None
24 | });
25 | }
26 | catch (Exception ex)
27 | {
28 | Debug.WriteLine($"Unable to launch maps: {ex.Message}");
29 | await Shell.Current.DisplayAlert("Error, no Maps app!", ex.Message, "OK");
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.31611.283
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonkeyFinder", "MonkeyFinder\MonkeyFinder.csproj", "{C60F2B1C-790E-4432-A719-52182A333ADE}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{393B8F30-F402-46A9-B209-8C71897A3416}"
9 | ProjectSection(SolutionItems) = preProject
10 | ..\Directory.build.props = ..\Directory.build.props
11 | ..\Directory.build.targets = ..\Directory.build.targets
12 | README.md = README.md
13 | EndProjectSection
14 | EndProject
15 | Global
16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 | Debug|Any CPU = Debug|Any CPU
18 | Release|Any CPU = Release|Any CPU
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
24 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {C60F2B1C-790E-4432-A719-52182A333ADE}.Release|Any CPU.Deploy.0 = Release|Any CPU
27 | EndGlobalSection
28 | GlobalSection(SolutionProperties) = preSolution
29 | HideSolutionNode = FALSE
30 | EndGlobalSection
31 | GlobalSection(ExtensibilityGlobals) = postSolution
32 | SolutionGuid = {61F7FB11-1E47-470C-91E2-47F8143E1572}
33 | EndGlobalSection
34 | EndGlobal
35 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/App.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class App : Application
4 | {
5 | public App()
6 | {
7 | InitializeComponent();
8 |
9 | MainPage = new AppShell();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/AppShell.xaml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
35 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/AppShell.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class AppShell : Shell
4 | {
5 | public AppShell()
6 | {
7 | InitializeComponent();
8 |
9 | Routing.RegisterRoute(nameof(DetailsPage), typeof(DetailsPage));
10 | }
11 | }
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/GlobalUsings.cs:
--------------------------------------------------------------------------------
1 | global using CommunityToolkit.Mvvm.ComponentModel;
2 | global using CommunityToolkit.Mvvm.Input;
3 | global using MonkeyFinder.Model;
4 | global using MonkeyFinder.ViewModel;
5 | global using System.Collections.ObjectModel;
6 | global using System.ComponentModel;
7 | global using System.Diagnostics;
8 | global using System.Runtime.CompilerServices;
9 | global using System.Text.Json;
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/MauiProgram.cs:
--------------------------------------------------------------------------------
1 | using MonkeyFinder.Services;
2 | using MonkeyFinder.View;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public static class MauiProgram
7 | {
8 | public static MauiApp CreateMauiApp()
9 | {
10 | var builder = MauiApp.CreateBuilder();
11 | builder
12 | .UseMauiApp()
13 | .ConfigureFonts(fonts =>
14 | {
15 | fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
16 | });
17 |
18 | builder.Services.AddSingleton(Connectivity.Current);
19 | builder.Services.AddSingleton(Geolocation.Default);
20 | builder.Services.AddSingleton(Map.Default);
21 |
22 | builder.Services.AddSingleton();
23 | builder.Services.AddSingleton();
24 | builder.Services.AddSingleton();
25 |
26 | builder.Services.AddTransient();
27 | builder.Services.AddTransient();
28 |
29 | return builder.Build();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Model/Monkey.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.Model;
2 |
3 | public class Monkey
4 | {
5 | public string Name { get; set; }
6 | public string Location { get; set; }
7 | public string Details { get; set; }
8 | public string Image { get; set; }
9 | public int Population { get; set; }
10 | public double Latitude { get; set; }
11 | public double Longitude { get; set; }
12 | }
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/MonkeyFinder.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0-android;net6.0-ios;net6.0-maccatalyst
5 | $(TargetFrameworks);net6.0-windows10.0.19041
6 | Exe
7 | MonkeyFinder
8 | true
9 | true
10 | enable
11 |
12 |
13 | MonkeyFinder
14 |
15 |
16 | com.companyname.monkeyfinder
17 | ECD44DAE-B03E-4D8B-B427-71865961E696
18 |
19 |
20 | 1.0
21 | 1
22 |
23 |
24 | True
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Platforms/Android/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Platforms/Android/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 |
3 |
4 | [assembly: UsesPermission(Android.Manifest.Permission.AccessCoarseLocation)]
5 | [assembly: UsesPermission(Android.Manifest.Permission.AccessFineLocation)]
6 | [assembly: UsesFeature("android.hardware.location", Required = false)]
7 | [assembly: UsesFeature("android.hardware.location.gps", Required = false)]
8 | [assembly: UsesFeature("android.hardware.location.network", Required = false)]
9 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)]
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Platforms/Android/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Content.PM;
3 | using Android.OS;
4 |
5 | namespace MonkeyFinder;
6 |
7 | [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize)]
8 | public class MainActivity : MauiAppCompatActivity
9 | {
10 | }
11 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Platforms/Android/MainApplication.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Runtime;
3 |
4 | namespace MonkeyFinder;
5 |
6 | [Application]
7 | public class MainApplication : MauiApplication
8 | {
9 | public MainApplication(IntPtr handle, JniHandleOwnership ownership)
10 | : base(handle, ownership)
11 | {
12 | }
13 |
14 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
15 | }
16 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Platforms/Android/Resources/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #512BD4
4 | #2B0B98
5 | #2B0B98
6 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Platforms/MacCatalyst/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 |
3 | namespace MonkeyFinder;
4 |
5 | [Register("AppDelegate")]
6 | public class AppDelegate : MauiUIApplicationDelegate
7 | {
8 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
9 | }
10 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Platforms/MacCatalyst/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIDeviceFamily
6 |
7 | 1
8 | 2
9 |
10 | UIRequiredDeviceCapabilities
11 |
12 | arm64
13 |
14 | UISupportedInterfaceOrientations
15 |
16 | UIInterfaceOrientationPortrait
17 | UIInterfaceOrientationLandscapeLeft
18 | UIInterfaceOrientationLandscapeRight
19 |
20 | UISupportedInterfaceOrientations~ipad
21 |
22 | UIInterfaceOrientationPortrait
23 | UIInterfaceOrientationPortraitUpsideDown
24 | UIInterfaceOrientationLandscapeLeft
25 | UIInterfaceOrientationLandscapeRight
26 |
27 | XSAppIconAssets
28 | Assets.xcassets/appicon.appiconset
29 | NSLocationWhenInUseUsageDescription
30 | Need to find monkeys!
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Platforms/MacCatalyst/Program.cs:
--------------------------------------------------------------------------------
1 | using ObjCRuntime;
2 | using UIKit;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public class Program
7 | {
8 | // This is the main entry point of the application.
9 | static void Main(string[] args)
10 | {
11 | // if you want to use a different Application Delegate class from "AppDelegate"
12 | // you can specify it here.
13 | UIApplication.Main(args, null, typeof(AppDelegate));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Platforms/Windows/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Platforms/Windows/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 |
3 | // To learn more about WinUI, the WinUI project structure,
4 | // and more about our project templates, see: http://aka.ms/winui-project-info.
5 |
6 | namespace MonkeyFinder.WinUI;
7 |
8 | ///
9 | /// Provides application-specific behavior to supplement the default Application class.
10 | ///
11 | public partial class App : MauiWinUIApplication
12 | {
13 | ///
14 | /// Initializes the singleton application object. This is the first line of authored code
15 | /// executed, and as such is the logical equivalent of main() or WinMain().
16 | ///
17 | public App()
18 | {
19 | this.InitializeComponent();
20 | }
21 |
22 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Platforms/Windows/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 | MonkeyFinder
16 | Microsoft
17 | appiconStoreLogo.png
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
39 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Platforms/Windows/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 | true/PM
12 | PerMonitorV2, PerMonitor
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Platforms/iOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 |
3 | namespace MonkeyFinder;
4 |
5 | [Register("AppDelegate")]
6 | public class AppDelegate : MauiUIApplicationDelegate
7 | {
8 | protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
9 | }
10 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Platforms/iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | LSRequiresIPhoneOS
6 |
7 | UIDeviceFamily
8 |
9 | 1
10 | 2
11 |
12 | UIRequiredDeviceCapabilities
13 |
14 | arm64
15 |
16 | UISupportedInterfaceOrientations
17 |
18 | UIInterfaceOrientationPortrait
19 | UIInterfaceOrientationLandscapeLeft
20 | UIInterfaceOrientationLandscapeRight
21 |
22 | UISupportedInterfaceOrientations~ipad
23 |
24 | UIInterfaceOrientationPortrait
25 | UIInterfaceOrientationPortraitUpsideDown
26 | UIInterfaceOrientationLandscapeLeft
27 | UIInterfaceOrientationLandscapeRight
28 |
29 | XSAppIconAssets
30 | Assets.xcassets/appicon.appiconset
31 | NSLocationWhenInUseUsageDescription
32 | Need to find monkeys!
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Platforms/iOS/Program.cs:
--------------------------------------------------------------------------------
1 | using ObjCRuntime;
2 | using UIKit;
3 |
4 | namespace MonkeyFinder;
5 |
6 | public class Program
7 | {
8 | // This is the main entry point of the application.
9 | static void Main(string[] args)
10 | {
11 | // if you want to use a different Application Delegate class from "AppDelegate"
12 | // you can specify it here.
13 | UIApplication.Main(args, null, typeof(AppDelegate));
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "Windows Machine": {
4 | "commandName": "MsixPackage",
5 | "nativeDebugging": false
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Resources/Fonts/OpenSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Part 6 - AppThemes/MonkeyFinder/Resources/Fonts/OpenSans-Regular.ttf
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Resources/Images/nodata.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Part 6 - AppThemes/MonkeyFinder/Resources/Images/nodata.png
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Resources/Raw/AboutAssets.txt:
--------------------------------------------------------------------------------
1 | Any raw assets you want to be deployed with your application can be placed in
2 | this directory (and child directories) and given a Build Action of "MauiAsset":
3 |
4 |
5 |
6 | These files will be deployed with you package and will be accessible using .NET MAUI:
7 |
8 | async Task LoadMauiAsset()
9 | {
10 | using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
11 | using var reader = new StreamReader(stream);
12 |
13 | var contents = reader.ReadToEnd();
14 | }
15 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Resources/appicon.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Resources/appiconfg.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/Services/MonkeyService.cs:
--------------------------------------------------------------------------------
1 | using System.Net.Http.Json;
2 |
3 | namespace MonkeyFinder.Services;
4 |
5 | public class MonkeyService
6 | {
7 | HttpClient httpClient;
8 | public MonkeyService()
9 | {
10 | this.httpClient = new HttpClient();
11 | }
12 |
13 | List monkeyList;
14 | public async Task> GetMonkeys()
15 | {
16 | if (monkeyList?.Count > 0)
17 | return monkeyList;
18 |
19 | // Online
20 | /*var response = await httpClient.GetAsync("https://www.montemagno.com/monkeys.json");
21 | if (response.IsSuccessStatusCode)
22 | {
23 | monkeyList = await response.Content.ReadFromJsonAsync>();
24 | }*/
25 |
26 | // Offline
27 | using var stream = await FileSystem.OpenAppPackageFileAsync("monkeydata.json");
28 | using var reader = new StreamReader(stream);
29 | var contents = await reader.ReadToEndAsync();
30 | monkeyList = JsonSerializer.Deserialize>(contents);
31 |
32 | return monkeyList;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/View/DetailsPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
17 |
27 |
34 |
35 |
36 |
37 |
38 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/View/DetailsPage.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder;
2 |
3 | public partial class DetailsPage : ContentPage
4 | {
5 | public DetailsPage(MonkeyDetailsViewModel viewModel)
6 | {
7 | InitializeComponent();
8 | BindingContext = viewModel;
9 | }
10 | }
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/View/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.View;
2 |
3 | public partial class MainPage : ContentPage
4 | {
5 | public MainPage(MonkeysViewModel viewModel)
6 | {
7 | InitializeComponent();
8 | BindingContext = viewModel;
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/ViewModel/BaseViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.ViewModel;
2 |
3 | public partial class BaseViewModel : ObservableObject
4 | {
5 | [ObservableProperty]
6 | [NotifyPropertyChangedFor(nameof(IsNotBusy))]
7 | bool isBusy;
8 |
9 | [ObservableProperty]
10 | string title;
11 |
12 | public bool IsNotBusy => !IsBusy;
13 | }
14 |
--------------------------------------------------------------------------------
/Part 6 - AppThemes/MonkeyFinder/ViewModel/MonkeyDetailsViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace MonkeyFinder.ViewModel;
2 |
3 | [QueryProperty(nameof(Monkey), "Monkey")]
4 | public partial class MonkeyDetailsViewModel : BaseViewModel
5 | {
6 | IMap map;
7 | public MonkeyDetailsViewModel(IMap map)
8 | {
9 | this.map = map;
10 | }
11 |
12 | [ObservableProperty]
13 | Monkey monkey;
14 |
15 | [RelayCommand]
16 | async Task OpenMap()
17 | {
18 | try
19 | {
20 | await map.OpenAsync(Monkey.Latitude, Monkey.Longitude, new MapLaunchOptions
21 | {
22 | Name = Monkey.Name,
23 | NavigationMode = NavigationMode.None
24 | });
25 | }
26 | catch (Exception ex)
27 | {
28 | Debug.WriteLine($"Unable to launch maps: {ex.Message}");
29 | await Shell.Current.DisplayAlert("Error, no Maps app!", ex.Message, "OK");
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/README.zh-cn.md:
--------------------------------------------------------------------------------
1 | # .NET MAUI - 动手实验手册
2 |
3 | 今天我们将会构建一个 [.NET MAUI](https://docs.microsoft.com/dotnet/maui?WT.mc_id=friends-mauiworkshop-jamont) 的应用程序,它将显示来自世界各地的猴子列表。 我们将从构建业务逻辑后端开始,该后端从 RESTful 端点提取 json 编码的数据。 然后,我们将利用 [.NET MAUI](https://docs.microsoft.com/xamarin/essentials/index?WT.mc_id=friends-mauiworkshop-jamont) 找到离我们最近的猴子,并将猴子展示在地图上。 我们还将学习到如何用多种不同的方式显示数据,最后开发一个完整的主题化应用程序。
4 |
5 | ## 动手实验环境需知
6 | 本次实验将是一个需要动手和自备设备的实验。您可以在 PC(推荐)或 Mac 上进行开发,您需要做的就是安装带有 .NET MAUI workload 的 Visual Studio 2022 或 Visual Studio for Mac 2022。
7 |
8 | 在开始本实验系列之前,我建议先用10分钟快速阅读 [.NET MAUI 教程](https://docs.microsoft.com/dotnet/maui/get-started/first-app?WT.mc_id=friends-mauiworkshop-jamont),它将指导您完成安装和正确配置好所需要的实验环境。
9 |
10 | 如果您是移动应用开发的新手,我们建议您把应用直接部署到 Android 设备(只需几个步骤即可完成有关设置)。如果您没有设备,请不用担心,因为您可以设置 [具有硬件加速功能的 Android 模拟器](https://docs.microsoft.com/xamarin/android/get-started/installation/android-emulator?WT.mc_id=friends-mauiworkshop-jamont)。如果您没有时间提前准备好相关设置,也不要担心,因为我们会在实验期间提供有关的提示和帮助。
11 |
12 | ## 实验内容
13 |
14 | 这是本次实验的有关内容:
15 |
16 | * [实验准备](Part%200%20-%20Overview/README.zh-cn.md) - 介绍 .NET MAUI 基本知识以及环境安装
17 | * [实验一: 显示数据](Part%201%20-%20Displaying%20Data/README.zh-cn.md) - 实现单页数据列表
18 | * [实验二: MVVM 和数据绑定](Part%202%20-%20MVVM/README.zh-cn.md) - MVVM 设计模式和数据绑定
19 | * [实验三: 添加导航页面](Part%203%20-%20Navigation/README.zh-cn.md) - 为应用添加导航
20 | * [实验四: 访问平台特性](Part%204%20-%20Platform%20Features/README.zh-cn.md) - 实现不同平台特定功能
21 | * [实验五: 为 CollectionView 添加下拉刷新](Part%205%20-%20CollectionView/README.md) - CollectionView 使用技巧
22 | * [实验六: 应用程序主题设置](Part%206%20-%20AppThemes/README.zh-cn.md) - 主题化应用
23 |
24 |
25 | 要开始使用,请打开“Part 1 - Displaying Data”文件夹并打开“MonkeyFinder.sln”。 您可以在整个实验过程中使用该项目。 每个**实验**都有一个 **README** 文件,其中包含该步骤实验过程的说明。 您也可以打开任何步骤的文件夹,里面都有一个和步骤对应的项目,您也可以打开来查看每一步的实现。
26 |
27 | ## 教学视频
28 | James 已经录制了4个小时的完整有关本次实验的手把手教学视频,各位小伙伴请到 [James 的 YouTube 频道](https://youtube.com/jamesmontemagno) 观看
29 |
30 | ## 更多链接和资源:
31 | - [.NET MAUI 官方网站](https://dot.net/maui)
32 | - [Microsoft Learn 上的 .NET MAUI 的学习路径](https://aka.ms/Learn.MAUI)
33 | - [.NET MAUI 官方文档](https://aka.ms/Docs.MAUI)
34 | - [GitHub 上的 .NET MAUI 项目](https://github.com/dotnet/maui)
35 | - [.NET 初学者入门系列视频](https://dot.net/videos)
36 |
37 |
38 | 如果您有任何问题,请在 Twitter 上与[@JamesMontemagno](https://twitter.com/jamesmontemagno) 联系。
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Slides/Workshop0 - Introduction to .NET MAUI.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Slides/Workshop0 - Introduction to .NET MAUI.pptx
--------------------------------------------------------------------------------
/Slides/Workshop1 - Our First App.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Slides/Workshop1 - Our First App.pptx
--------------------------------------------------------------------------------
/Slides/Workshop2 - MVVM and Data Binding.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Slides/Workshop2 - MVVM and Data Binding.pptx
--------------------------------------------------------------------------------
/Slides/Workshop3 - Navigation.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Slides/Workshop3 - Navigation.pptx
--------------------------------------------------------------------------------
/Slides/Workshop4 - Accessing Platform Features.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Slides/Workshop4 - Accessing Platform Features.pptx
--------------------------------------------------------------------------------
/Slides/Workshop5 - CollectionView.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Slides/Workshop5 - CollectionView.pptx
--------------------------------------------------------------------------------
/Slides/Workshop6 - App Themes.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kinfey/dotnet-maui-workshop/a010a0228645d6b8a4d91124f8514f52dd4aefeb/Slides/Workshop6 - App Themes.pptx
--------------------------------------------------------------------------------