Joined today by Mads and Dustin to discuss what’s new in C# 11 with a focus on when application developers will use the new features.

that the person he is talking to (cropped out) is Dustin!
Joined today by Mads and Dustin to discuss what’s new in C# 11 with a focus on when application developers will use the new features.
Building on the previous postings, today I want to discuss the magic of Dependency Injection (DI)
Dependency Injection makes for cleaner and more testable code. We’ll get into testing and Mocks in a later blog post, but using DI allows you to substitute a mock service for a real one. In any case, it is magical.
Even though this is powerful, this posting will be short, because once you know how to do it, it is very easy.
Let’s look at BuddyPreferences. This is the page that lists all the preferences of a specific buddy. We start, in BuddyPreferences.xaml.cs by creating BuddyPreferencesViewModel so that it can be our BindingContext. We pass the ViewModel into the constructor. Here is the complete class:
public partial class BuddyPreferences : ContentPage
{
private BuddyPreferencesViewModel vm;
public BuddyPreferences(BuddyPreferencesViewModel vm)
{
this.vm = vm;
BindingContext = vm;
InitializeComponent();
}
}
Continue reading This is part 4 in an ongoing series in which I will build and dissect a non-trivial app. For details, please see the first in this series.
Part 3 ended with a teaser about the Preferences Page. As you’ll remember, we start with the Preference Model class:
namespace ForgetMeNot.Model;
[ObservableObject]
public partial class Preference
{
[ObservableProperty] private string preferencePrompt;
[ObservableProperty] private string preferenceValue;
}
I explained about ObservableProperties, so I won’t review that here. Let’s see how this model class is used. There are two important related classes: Preferences.xaml and PreferencesViewModel.cs
Continue readingIn the previous postings we looked at creating the basic app and adding a single, simple page. This post will really begin to get into it.
We’re going to have a number of pages
Each of these pages will have its own viewmodel class. We’ll also need services to talk to the API client (e.g., BuddyService with methods to get your buddy list, add to your list, see your buddy’s preferences, etc.)
Continue readingIn Part 1 we created the skeleton of Forget Me Not (and explained what it is). Here in Part 2 we’ll add an about page. This is so easy that this will be a short post.
Creating the page is almost indistinguishable from doing so in Xamarin.Forms. Here’s the XAML for the page:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
x:Class="ForgetMeNot.About"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<VerticalStackLayout Margin="10" Spacing="10">
<HorizontalStackLayout Spacing="10">
<Image HeightRequest="64" Source="flower.png" />
<Label
FontAttributes="Bold"
FontSize="22"
Text="About this app"
VerticalOptions="End" />
<Label
FontSize="22"
Text="v1.0"
VerticalOptions="End" />
</HorizontalStackLayout>
<Label Text="This app is written in XAML and C# with .NET MAUI by Jesse Liberty and Rodrigo Juarez. Concept and original design by Robin Liberty" />
</VerticalStackLayout>
</ContentPage>
We put a picture of a forget-me-not flower next to the title. Below that is the version and the acknowledgements. We’ll want to be able to navigate to the About page using a tab at the bottom of the page, so let’s turn to AppShell.xaml and ad the tab there:
<TabBar>
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:MainPage}"
Icon="icon_notes" />
<ShellContent
Title="About"
ContentTemplate="{DataTemplate local:About}"
Icon="icon_about" />
Next we open AppShell.xaml.cs and add the route
public AppShell()
{
InitializeComponent();
Routing.RegisterRoute("about", typeof(About));
}
That’s it! We created the page, created the tab and told MAUI where to find the page by registering the route.
My buddy in Argentina, Roberto Juarez, and I have set out to create a real-world, non-trivial program using .NET MAUI. This is a learning exercise, and I’d like to invite you to join us. We anticipate that (eventually) this will be in the stores, and we hope it will be open source (we are discussing a commercial video which might get in the way of giving away the copyright, but the source will definitely be available).
You can see an associated video here.
Associated (partial) code here.
This app was conceived and designed by Robin Liberty.
The premise is that you want to buy gifts for your “buddies,” and allow them to buy gifts for you. You start by filling out our form on your preferences (shirt size, favorite books, favorite food, etc. ect.). You then invite others to join (securely). Once they register as your buddy, they can see your list and you can see theirs. You can have as many buddies as you want, but the sharing is always 1:1.
In addition, you can put in shared occasions (birthdays, anniversaries, etc.) and be notified when one is coming up so you have time to buy a gift.
The server will provide an API for the client so that we can manage most of the data in the cloud (certain set-up preferences will be stored locally). In version 1 this is an on-line only app, running only on iOS, Android and Windows (though in theory it should also run on MacOS, watch, etc.)
Continue readingLists are always subjective, but it is helpful, I think, to exchange favorites now and again. Feel free to add yours to the comments. Here’s my list in no particular order
Note that nearly all of these are free (not Resharper, LastPass, Github Copilot, Beyond Compare, One Note). I do remember the days when a program like Lotus 123 cost something in the hundreds of dollars. Makes me laugh when I see people look at an app and say “$4.00, naah too expensive.”
As I say, grab these, and if there are others that you use, please note them in the comments.
Thanks
So let’s talk about something we don’t talk about. Many of us (programmers) are significantly overweight. You see it at every conference. I’ve heard 3xl referred to as a programmer’s medium.
This year I decided to do something about it before it (literally) kills me.
On May 17 I began the process and lost 55# before having a Bariatric Sleeve Gastrectomy. at Emerson Hospital in Concord MA (they were truly great).
My goal is to lose another 90#, about 60 of that this year. We’ll see.
I’m not advocating surgery; I’m not advocating anything, except that we take this out of the “we don’t talk about that” box and open up the discussion.
Feel free to comment or ignore, but let’s keep the discussion friendly.
Follow up December 2024. I overshot my goal. I had hoped to get down to 220, then to 200, but ended up at 190. It has changed my life, all for the good.
The truth is, the first year is miserable, but then it becomes effortless. I can’t recommend surgery… what do I know?… but for me it was one of the best things I’ve done.
As an experienced XF programmer, you know that there are times you need a relational database, and SQLite has been the mobile db of choice for a very long time. In this post we’ll create a table in SQLite and if it has anything in it, we’ll display the contents of the table. If it is empty, we’ll go out to the service, get our data, and stash it in the table.
For the purposes of this demo, I’m only going to create one table, after that it is just SQL.
Picking up where we left off, the first thing you’ll need are a couple NuGet packages.
The bulk of the changes happen in ZipCodeService
Continue readingVery 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.
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.
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