Maddy Montaquila on .NET MAUI

Very excited to have Maddy back on Yet Another Podcast. Today we go beyond the basics to intermediate and advanced topics in .NET MAUI.

Or wherever you get your podcasts.

Posted in Essentials | Tagged | Leave a comment

Learning .NET MAUI – Part 14

Have I thanked James Montemagno yet? His 4 hour training video is the foundation of this series of posts (with his permission).

Part 0 which kicks off this series is here.

Platform Specific Services

Now that we’ve covered platform services from MAUI, what about platform-specific issues? For example, iOS has to deal with the notch at the top of the screen, while Android, Windows, etc. do not. To solve this, add a namespace:

xmlns:ios="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;assembly=Microsoft.Maui.Controls"

If you just type xmlns:ios=ios it will offer the entire string for completion

After saving that, and still in the ContentPage element you can then add

ios:Page.UseSafeArea="True"

This avoids the kind of platform if/else statements we were used to.

Continue reading
Posted in Essentials | Leave a comment

Learning .NET MAUI – Part 13

In this post we’ll do three things:

  • Add a clear button to clear out the list of zip codes
  • Add the Connected service to make sure we have internet connection before trying to get the zip codes
  • Add the IMap service to show a map of a place
Continue reading
Posted in Essentials | Tagged , | Leave a comment

Learning .NET MAUI – Part 12

We left off displaying the zip codes and going to the details, but not displaying the selected zip code. Let’s fix that and clean some things up.

Choosing from the list and displaying the details

In the previous version we hard coded which result would be passed to the details page. Getting the actual selection is not terribly difficult. First modify MainPage.xaml

<CollectionView ItemsSource="{Binding Results}" SelectionMode="None">
    <CollectionView.ItemTemplate>
        <DataTemplate x:DataType="model:Result">
            <Grid Padding="10">
                <Grid.GestureRecognizers>
                    <TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MainViewModel}}, Path=GoToZipCodeDetailsCommand}" CommandParameter="{Binding .}" />
                </Grid.GestureRecognizers>
                <VerticalStackLayout>
                    <HorizontalStackLayout
                        Padding="10"
                        Spacing="4"
                        VerticalOptions="Center">
                        <Label VerticalOptions="Center">
                            <Label.Text>
                                <MultiBinding StringFormat="{}{0}, {1}  {2}">
                                    <Binding Path="city" />
                                    <Binding Path="state" />
                                    <Binding Path="zip" />
                                </MultiBinding>
                            </Label.Text>
                        </Label>
                    </HorizontalStackLayout>
                </VerticalStackLayout>
            </Grid>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

Note that I’ve added a grid, put the TapGestureRecognizer on that structure, so that it is within the datatemplate.

Continue reading
Posted in Essentials | Tagged , | Leave a comment

Learning .NET MAUI – Part 11

This one should be short. We’re going to take a look at passing values when navigating.

Passing in values requires that you pass a Dictionary, where the key is an arbitrary string and the object is the value you are passing

 [ICommand]
 async Task GoToZipCodeDetailsAsync()
 {

     Result result = new Result
     {
         zip = "01720",
         city = "Acton",
         state = "MA"
     };

     
     try
     {
          await Shell.Current.GoToAsync($"ZipCodeDetailsPage", true,
             new Dictionary<string, object>
         {
                 
             { nameof(Result), result }
         });               
     }
     catch(Exception ex)
     {
         Debug.WriteLine(ex.Message);
         await Shell.Current.DisplayAlert("Unable to go to Details page!", ex.Message, "OK");
     }
 }

You would normally pass the Result object into GoToZipCodeDetailsAsync, but here I’m creating it on the fly for demonstration purposes.

ZipCodeDetailsPage is the page we are navigating to. true means we do want animation on the page change and the Dictionary contains a key and a value, in this case the Results collection.

To receive this in the called page, go to the ZipCodeDetailsViewModel and add this to the top (before the class name:

[QueryProperty(nameof(Result), “Result”)]

The first value (nameof(Result) will signal the name of the property, the second will be the value for that property (Result) You want to match this with a property in the class which you do just by declaring the property:

[ObservableProperty]
Result result;

We are now in a position to bind to that property

<VerticalStackLayout>
    <Label
        HorizontalOptions="Center"
        Text="Welcome to .NET MAUI!"/>
    <VerticalStackLayout>
        <Label Text="You made it to the details page!" />
        <Label Text="{Binding Result.city}" />
        <Label Text="{Binding Result.state}" />
        <Label Text="{Binding Result.zip}" />
    </VerticalStackLayout>
</VerticalStackLayout>

That’s really all there is to it.

The source code is here

Posted in Essentials | Tagged , | Leave a comment

Learning .NET MAUI – Part 10

Let’s take a quick look at simple navigation (in the next post we’ll look at some more you can do with navigation. As usual, we’ll start with the previous day’s code.

To get started, we’ll add a button to the main page that will take us to the details page. This is a very common paradigm, seen in almost every program sooner or later.

Continue reading
Posted in Essentials | Tagged , | Leave a comment

Learning .NET MAUI – Part 9

Once again, we’ll pick up where we left off. But today we’re in for some big changes.

Let’s add an IsBusy property to use in the MainViewModel. We’ll use the same trick we did with _resultList:

[ObservableProperty]

public bool _isBusy;

Let’s further assume you want an _isNotBusy. There are two ways to accomplish this. One is with a converter from the CommunityToolkit, specifically the InvertBoolConverter. A second option is just to create another member:

public bool _isNotBusy => !IsBusy;

The problem you have is that when IsBusy is changed, you want _isNotBusy to be updated as well. There’s an attribute for that…

[ObservableProperty]
[AlsoNotifyChangeFor(nameof(_isNotBusy))]
public bool _isBusy;

Very clean and tidy.

Continue reading
Posted in Essentials | Tagged , | Leave a comment

Learning .NET MAUI – Part 8

Busy week, so this one will be short. I’ve taken the code from Part 7 and copied it into Part 8. The source for 8 is here. So, what’s new?

The most important improvement in 8 is the addition of Community Toolkit for Maui and the Microsoft toolkit for MVVM. Open your “Manage NuGet Packages” window and check that you have or add these packages

  • CommunityToolkit.Maui
  • CommunityToolkit.Maui.Core
  • Microsoft.MauiDependencies
  • Microsoft.Maui.Extensions
  • Microsoft.Toolkit.Mvvm

This allows you to make some magic. The most impressive of which is how much code you will no longer have to write, because the MVVM kit provides code generators. We’ll see a lot more of this as we go, but let’s get started by making some changes.

Continue reading
Posted in Essentials | Tagged , | Leave a comment

Learning .NET MAUI – Part 7

Let’s pick up where we left off in the previous blog post, but it is time to clean up the app to use MVVM. First step: create a ViewModel folder and in that put two files:

  • MainViewModel
  • ViewModelBase
Continue reading
Posted in Essentials | Tagged , | Leave a comment

Learning .NET MAUI – Part 6

I’m going to start off where we were at the end of Part 5, but this time instead of creating two labels (for State and Zip) I’m going to create one label with MultiBinding:

  <Label VerticalOptions="Center">
     <Label.Text>
         <MultiBinding StringFormat="{}{0} | {1}">
             <Binding Path="state" />
             <Binding Path="zip" />
         </MultiBinding>
     </Label.Text>
 </Label>

This is more efficient and also allows me to put VerticalOptions=”Center” into the label tag and have it affect all the contained labels. This is a nice alternative to having to use the HorizontalStackLayout

NB: You can continue to use the Xamarin.Forms <StackLayout> element, but HorizontalStackLayout and VerticalStackLayout have been optimized and thus are preferred.

Continue reading
Posted in Essentials | Tagged , , | Leave a comment

Learning .NET MAUI – Part 5

When last we looked, we were returning a few countries. Let’s use ZipWise’s ability to look up a city name and give us all the info about all matching cities. We’ll then have fun with displaying that info.

When I ask for all cities named Middletown I get a nice set of results

{"results":[{"zip":"02842","city":"Middletown","state":"RI"},{"zip":"05143","city":"Middletown","state":"VT"},{"zip":"06457","city":"Middletown","state":"CT"},{"zip":"06459","city":"Middletown","state":"CT"},{"zip":"07748","city":"Middletown","state":"NJ"},{"zip":"10940","city":"Middletown","state":"NY"},{"zip":"10941","city":"Middletown","state":"NY"},{"zip":"17057","city":"Middletown","state":"PA"},{"zip":"19709","city":"Middletown","state":"DE"},{"zip":"21769","city":"Middletown","state":"MD"},{"zip":"22645","city":"Middletown","state":"VA"},{"zip":"22649","city":"Middletown","state":"VA"},{"zip":"40243","city":"Middletown","state":"KY"},{"zip":"40253","city":"Middletown","state":"KY"},{"zip":"45005","city":"Middletown","state":"OH"},{"zip":"45042","city":"Middletown","state":"OH"},{"zip":"45044","city":"Middletown","state":"OH"},{"zip":"47356","city":"Middletown","state":"IN"},{"zip":"52638","city":"Middletown","state":"IA"},{"zip":"62666","city":"Middletown","state":"IL"},{"zip":"63359","city":"Middletown","state":"MO"},{"zip":"95461","city":"Middletown","state":"CA"},{"zip":"05757","city":"Middletown Springs","state":"VT"},{"zip":"19056","city":"Middletown Twp","state":"PA"},{"zip":"07748","city":"N Middletown","state":"NJ"},{"zip":"40357","city":"N Middletown","state":"KY"},{"zip":"44442","city":"New Middletown","state":"OH"},{"zip":"47160","city":"New Middletown","state":"IN"},{"zip":"07748","city":"North Middletown","state":"NJ"},{"zip":"40357","city":"North Middletown","state":"KY"},{"zip":"15379","city":"W Middletown","state":"PA"},{"zip":"45042","city":"W Middletown","state":"OH"},{"zip":"15379","city":"West Middletown","state":"PA"}]}

I’ll leave it to you to put this into Json Prettifier as the result is pretty long for a blog post. We do, now, have a nice list of cities we can display, along with their states and zip codes.

Continue reading
Posted in Essentials | Leave a comment

Learning .NET MAUI – Part 4

We’ve seen how to get a single zip code and display it in a series of labels. Let’s use a collection to take a look at how we might deal with that in MAUI. To get started, we’ll create a new MAUI application named MultipleZip. Throw away what is in MainPage.xaml and MainPage.xaml.cs. You should have a nice clean slate.

Continue reading
Posted in Essentials | Tagged | Leave a comment