MAUI Learning Projects
ColorMaker
https://github.com/brettlazarine/ColorMakerMAUI
A fun, quick project led by Hector Perez on his Udemy course: .NET MAUI course with Visual Studio 2022 creating PROJECTS
The XAML is comprised of a Grid container, which holds a stack layout that contains labels and sliders that display the amount of red, green, and blue being added into a HEX color creator. These sliders receive their power from the codebehind, enabling them to combine together to create HEX values by manipulating the slider values. Below the sliders is a random button, that generates a random HEX color, and then an image that, when clicked, copies the HEX value to the user's clipboard.
The codebehind is managed by way of a few methods:
SetColor() assigns the HEX value to the lblHex label to display the value for the user, and changes the container and btnRandom background colors to the selected color
btnRandom_Clicked() invokes the Random class to create 3 random RGB values, and then assigns those values to the sliders
ImageButton_Clicked() puts the CommunityToolKit.Maui Nuget package to use, calling Toast.Make() from CommunityToolkit.Maui.Alerts in order to copy the HEX value by clicking the image next to the HEX value text
PerfectPay
https://github.com/brettlazarine/PerfectPayMAUI
Another great project led by Hector Perez on his Udemy course: .NET MAUI course with Visual Studio 2022 creating PROJECTS
This android app takes in a bill total, the amount of desired tip, and the number of people splitting the check. The program then calculates the amount of the bill that will be paid by each person. The XAML is comprised of a Grid container that is broken down into 2 sections, also Grid layouts. The top Grid holds the labels that display the pertinent bill information: the bill total (bill with tip), then a BoxView separating it from the information on the right half of the Grid, the subtotal (bill without tip), and the tip amount.
The bottom Grid container houses the functionality of the application:
An entry form that locks the Keyboard to Numeric, where the user can input their bill total
3 buttons that allow the user to quickly select from 10%, 15%, and 20% tip amounts
A slider, which allows the users to select a tip amount all the way up to 50%
2 buttons at the bottom which enable the user to increase/decrease the number of people splitting the check
The codebehind implements a method and the EventHandlers that make the application function:
CalculateTotal() calculates the tip, tip per person, subtotal, and total by person
It then updates these values for each of the x:Name components in the XAML so that the numbers are displayed correctly on the Page
This method is called in each subsequent EventHandler so that the values are constantly reflecting the changes made by the user
txtBill_Completed() parses the string from the entry form and converts it to a double, then assigns the value to the Property bill
sldTip_ValueChanged() casts the slider value to an int, and then updates lblTip's text with string interpolation
Button_Clicked() casts the Event's sender as a Button so that its properties can be accessed, replaces the % with an empty string so that the value can be parsed as an int, and subsequently updates the slider value with the value from the tip button that was clicked
btnMinus_Clicked() first checks that the value of Property noPersons is at least 1 (somebody's gotta pay the bill), and then allows the user to reduce the amount of people splitting the check down to no fewer than one person and updates lblNoPersons's text
btnPlus_Clicked() allows the users to add people splitting the check one at a time per click, and then updates lblNoPersons's text
CodeQuotes
https://github.com/brettlazarine/CodeQuotesMAUI
Another in-depth project led by Hector Perez on his Udemy course: .NET MAUI course with Visual Studio 2022 creating PROJECTS
The XAML on this project is fairly simple, with one Grid container holding the code for the entire application. The focus of this program is placed upon a label that displays quotes, a button that displays a random quote, and the imposition of a gradient background that is also randomized by the random quote button.
There are 2 additional resources added into this project:
quotes.txt is a text file placed in the Raw folder that holds all of the quotes utilized in the application
PTSerif-Regular.ttf is an external font that has been added to the project's Resources and applied to the font of the program
This font file is given the alias Serif in MauiProgram.cs
The codebehind achieves the desired behavior as follows:
LoadMauiAsset() is lifted from MauiProgram.cs and reads quotes.txt, then adds each quote to the quotes List<string> Property
OnAppearing() is overridden to call LoadMauiAsset() when the Page is loaded
btnGenerateQuote_Clicked() is the EventHandler that achieves the functionality of the program
startColor and endColor are created using the random instance of the Random Class, with the use of the FromArgb() method of the System.Drawing Class
The colors Collection is created to house the colors of the gradient, and the Float stopOffset is created for the assignment of the offsets of each color in the gradient
stops is then declared and in a foreach loop the gradient colors are assigned to an offset
gradient is the culmination of the work so far, taking on the stops Collection and the EndPoint, then assigning these values to the background of Grid background
The EndPoint is set to (1,1), which heads from the top-left to the bottom-right
Finally, Label quote is given a random quote by way of the Property quotes being accessed using a randomly generated index
HangmanGame
https://github.com/brettlazarine/HangmanGameMAUI
A quick, fun game led by Hector Perez on his Udemy course: .NET MAUI course with Visual Studio 2022 creating PROJECTS
The XAML is contained in a single Grid with 2 rows. The first row is a Vertical Stack Layout where the controls for display are kept. The second row is a Flex Layout with Wrap and SpaceEvenly attributes, which allows the Bindable Layout to create a code-generated on-screen keyboard.
The codebehind is powered by a number of Methods that perform the functionality of the application:
PickWord() selects a random word from the words List
CalculateWord() applies the guessed letter to Spotlight, and enters the letter if it was correct or _ if the guess was wrong
Button_Clicked() passes the letter of the Button that was clicked to the HandleGuess() method, and disables the Button
HandleGuess() checks whether the guess was correct or not
If correct, it calls CalculateWord() and CheckIfGameWon()
If wrong, mistakes is incremented, UpdateStatus() is called, calls CheckIfGameLost(), and updates CurrentImage to reflect the amount of incorrect guesses so far
CheckIfGameLost() checks if mistakes equals maxWrong and, if so: updates Message, applies answer to Spotlight, and calls DisableLetters()
DisableLetters() and EnableLetters() disable/enable the letter Buttons
CheckIfGameWon() verifies that Spotlight equals answer and, if so: updates Message and calls DisableLetters()
UpdateStatus() injects mistakes and maxWrong into a string that displays the user's progress towards failure
Reset_Clicked() resets all values to their base, selects a new word, and then calls EnableLetters()
BMICalculator
https://github.com/brettlazarine/BMICalculatorMAUI
An MVVM focused project led by Hector Perez on his Udemy course: .NET MAUI course with Visual Studio 2022 creating PROJECTS
The UI for this application is cleverly built out with Syncfusion 'gauges', allowing for a more visually satisfying look. The View is broken down into 3 portions: Height, Weight, and Result. Both Height and Weight implement LinearGauges with Sliders that update their own values and the Result value when the Sliders are moved. Result utilizes a RadialGauge broken down into each of the BMI categories that has a Pointer that updates with each of the Sliders, and has a Label that displays the BMI category dynamically.
The ViewModel simply implements the BMI Class to be used in the View. The BMI Model utilizes the PropertyChanged.Fody NuGet Package. This INCREDIBLY nifty Package adds the INotifyPropertyChanged Interface to a Class without actually requiring full implementation of the Interface itself. In doing so, a lot of code is spared from being written, which in turn makes the Class a much cleaner read.
UnitConverter
https://github.com/brettlazarine/UnitConverterMAUI
This is a View navigation focused project led by Hector Perez on his Udemy course: .NET MAUI course with Visual Studio 2022 creating PROJECTS
There are 2 Views that establish the application:
MenuView
A primary Grid container with 3 columns and 4 rows
Row 1 simply dispays the app's title, spanning all columns
The remaining 3 rows are broken down into each of the conversion categories, with FontImageSource Images from a loaded font fontello and TapGestureRecognizer Events attached to each as means of passing to their corresponding View
The Codebehind
TapGestureRecognizer_Tapped() captures the desired Label.Text value in option and passes it to the ConverterViewModel() Constructor
It then navigates to the ConverterView using the desired unit category
ConverterView
A primary Grid container broken into 2 rows
Row 1 displays the Entry and Picker where the user can select the units and values they want to see converted
Row 2 displays the conversion, along with another Picker to change the selected conversion unit type
All information is dynamically bound to the ViewModel so that only one View is required to display all requested information, rather than building out a View for each category
The Pickers implement SelectedIndexChanged so their selected unit will update displayed information
The Codebehind
Picker_SelectedIndexChanged() updates the Picker's value by calling the Convert() Method from ConverterViewModel
ConverterViewModel handles the logic of the application, utilizing the UnitsNet and Fody Nuget Packages. UnitsNet houses the logic for conversions and Fody implements INotifyPropertyChanged without needing any additional code.
The Constructor was overloaded to assign default values for when ConverterView is initially loaded.
Convert() puts UnitsNet to work and calculates converted values
LoadMeasures() selects the category from MenuView() and loads the List of units to the Pickers
Calculator
https://github.com/brettlazarine/CalculatorMAUI
A project focused on Style led by Hector Perez on his Udemy course: .NET MAUI course with Visual Studio 2022 creating PROJECTS
The XAML is designed in the layout of a typical cell phone calculator, keypad at the bottom and results at the top. The buttons each use Commands to achieve their part of calculating whatever equation the user wants. The Style for the application is achieved by way of CalcDictionary, a Style dictionary that defines the aesthetic of the various Controls. Phone dark and light themes are also taken into consideration, with AppThemeBinding implemented into the Style Dictionary to ensure the application will function regardless of the user's theme settings.
The ViewModel achieves the calculator functionality for the app:
OperationCommand adds the desired number/operand to Formula for calculation
ResetCommand returns Result and Formula to their default values
BackspaceCommand removes the last indexed value from Formula
CalculateCommand implements the Dangl.Calculator NuGet Package and calculates the result of the user's input
TaskerApp
https://github.com/brettlazarine/TaskerAppMAUI
This is a CollectionView focused app led by Hector Perez on his Udemy course: .NET MAUI course with Visual Studio 2022 creating PROJECTS
MainView is the primary View for displaying the List of tasks:
Label texts are bound to MainViewModel
The ProgressBar updates when the Tasks are checked off
The tasks themselves are also bound, and implement the Convert Converter to transform the Color property fom Hex and a DataTrigger that adds a Strikethrough to any checked off Tasks
Codebehind
Button_Clicked() creates an instance of NewTaskView with binding to NewTaskViewModel and then pushes to NewTaskView
NewTaskView allows the user to create new Categories and Tasks, then adds them to MainView
All data is bound, and the buttons house the Events that allow for Task and Category item creation
Codebehind
AddTaskClicked() applies the selected Category, adds the Task to the Tasks List, then Pops the View off
It also displays an Alert should the user try to add a Task without selecting a Category and prevents them from doing so
AddCategoryClicked() displays a Prompt that allows users to enter the name of the Category (15 characters max), then assigns a random color by way of utilizing the Random Class in Color.FromRgb()
The ViewModels and Models implement Fody for ease of INotifyPropertyChanged, and a custom Style AppStyles was created for ease of styling and consistency.
WeatherAppMAUI
https://github.com/brettlazarine/WeatherAppMAUI
This project focuses on the consumption of open-meteo's API to create a weather app, led by Hector Perez on his Udemy course: .NET MAUI course with Visual Studio 2022 creating PROJECTS
The UI is formatted to display data by way of binding to API specific Class Properties, implementing a CollectionView to display the future forecast, and utilizes LottieFiles to provide users with dynamic weather icons:
The styles for the controls are placed in the custom AppStyles ResourceDictionary
searchBar uses its SearchCommand and SearchCommandParameter to activate the backend logic that calls the API and generates information to be displayed
LottieImages and weather types are converted from weathercode to their appropriate animated images/values with CodeToLottieConverter and CodeToWeatherConverter
The Controls are hidden by default, and IsVisible is toggled after the API call
An ActivityIndicator is set within a Grid that has its IsVisible property bound to IsLoading that is toggled before and after the API call
The backend is powered by WeatherViewModel, and implements Fody for INotifyPropertyChanged:
SearchCommand formats PlaceName such that the first letter of any word entered into searchBar is capitalized, calls GetCoordinatesAsync(), and calls GetWeather()
GetCoordinatesAsync() implements the Geocoding Class and returns the location information (latitude and longitude in particular) of location
GetWeather() then utilizes location's information (lat and long) in the API call to open-meteo
IsLoading is set to True, activating the ActivityIndicator and its Grid's UI properties
response retrieves the data from the API and, if successful, is subsequently deserialized and the contents applied to WeatherData
Because WeatherData.daily is a List of values, it is iterated through and the values for each day are assigned to daily2, which is then added to the daily2 List for CollectionView
Finally, IsVisible is toggled to display all of the information returned from the API call and IsLoading is toggled to hide the ActivityIndicator and its Grid
Both CodeToWeatherConverter and CodeToLottieConverter use Switch Cases to compare and change weathercode against the corresponding weather code found in the API's documentation
ProsperDailyMAUI
https://github.com/brettlazarine/ProsperDailyMAUI
This is a project focusing on the implementation of SQLite, led by Hector Perez on his Udemy course: .NET MAUI course with Visual Studio 2022 creating PROJECTS
NuGet Packages
Humanizer adjusts the display template of OperationDate to give it a more appealing and friendly format
Fody implements INotifyPropertyChanged with minimal code
Syncfusion allows for the creation and binding of the StatisticsPage chart
SQLite allows for the creation of database storage for the application
Views
AppContainer creates a TabbedPage layout for ease of page navigation
DashboardPage acts as the MainPage, binding and displaying Model info that updates when new transactions are added
TransactionsPage allows for the creation of a Transaction
StatisticsPage displays the Transaction Collection like DashboardPage, but also displays a chart for a visual representation
ViewModels
DashboardViewModel implements FillData(), which orders Transactions and applies each transaction to Income or Expenses, then to Balance
TransactionsViewModel uses SaveTransaction() to save the created Transaction to the database
StatisticsViewModel utilizes GetTransactionSummary() to group and order all transactions for the chart in the View
Converters
AmountToColorConverter and AmountToCurrencyConverter detect if a Transaction is Income or Expense, and then applies the appropriate style to that Label
Repositories
BaseRepository houses all of the necessary Methods for interacting with the SQLite database