CHAPTER 6
Some of the features discussed in the previous chapters are empowered by new extension methods implemented by the.NET MAUI Community Toolkit. Such extension methods can also be used outside of the objects provided by the Toolkit and leveraged in your own scenarios. More specifically, you can animate and convert colors, and you can make the MAUI engine properly handle your views. These possibilities are all covered in this chapter.
Among others, the .NET MAUI Community Toolkit exposes three classes that define specific extension methods. These classes are referred to as extensions, and Table 7 summarizes them.
Table 7: Reusable Extensions
Extension | Description |
|---|---|
ColorAnimationExtensions | Expose extension methods that allow for animating properties of type Color. |
ColorConversionExtensions | Expose extension methods that convert an object of type Color into another Color or another type. |
ServiceCollectionExtensions | Expose extension methods that make it simpler to add views and their associated viewmodels to the app’s service collection. |
The next sections describe all the extension methods with suggestions about their use cases.
Two classes allow for working with colors: ColorAnimationExtensions and ColorConversionExtensions. These are described in the next sections.
The ColorAnimationExtensions class exposes two extension methods:
· BackgroundColorTo: This method animates the BackgroundColor property of those views where it is available, such as (but not limited to) Grid and Button.
· TextColorTo: This method animates the TextColor property of those views where it is available, such as Entry and Label.
Both methods require at least one argument, which is the target color for the animation. However, they share a full list of parameters described in Table 8.
Table 8: Common Method Parameters
Parameter | Type | Description |
|---|---|---|
color | Color | The target color for the animation. |
rate | uint | The time between frames of the animation in milliseconds. If omitted, the default is 16. |
length | uint | The duration of the animation in milliseconds. If omitted, the default is 250. |
easing | Easing | The easing function used for the animation. The default is null. |
Before using these methods, you need the following using directive.
using CommunityToolkit.Maui.Extensions;
For example, you could animate the background of a Label as follows.
var label = new Label { BackgroundColor = Colors.White };
await label.BackgroundColorTo(Colors.Red);
This code will animate the background color with the default values described in Table 8. You could then further customize the animation like in the following example.
await label.BackgroundColorTo(Colors.Red, 10, 180, Easing.Linear);
With this code, the time between frames is 10 milliseconds, the animation duration is 180 milliseconds, and the type of animation is the Linear one from the Easing collection. The sample project provides the ColorAnimationExtensionsPage.xaml file under the Pages\Extensions folder. If you run the example and start the animations, you will get a result similar to Figure 37.

Figure 37: Animating Colors
These methods are very useful when you need to capture the user’s attention, or when you simply want to provide a nice behavior to your user interface.
In Chapter 4, “Saving Time with Reusable Converters,” you saw how to convert one color to another color or one color to another type via value converters with data-binding scenarios. However, converting colors can also be useful outside of data binding. The value converters you saw in Chapter 4 all rely on separate methods that perform the actual conversions and are all defined inside the static ColorConversionExtensions class, located inside the ColorConversionExtensions.shared.cs file of the Toolkit. For example, if you want to convert a Color into a string that contains the RGB representation of the color, you can invoke an extension method called ToRgbString, as follows.
string resultString = Colors.Green.ToRgbString();
The extension method definition is:
public static string ToRgbString(this Color color)
{
ArgumentNullException.ThrowIfNull(color);
return $"RGB({color.GetByteRed()},{color.GetByteGreen()},{color.
GetByteBlue()})";
}
Tip: The this keyword in the parameter list identifies the definition of an extension method, together with the static modifier.
The GetByteRed, GetByteGreen, and GetByteBlue methods are defined in the same file and their purpose is to retrieve the color’s components. Their definition is:
public static byte GetByteRed(this Color color)
{
ArgumentNullException.ThrowIfNull(color);
return ToByte(color.Red * 255);
}
public static byte GetByteGreen(this Color color)
{
ArgumentNullException.ThrowIfNull(color);
return ToByte(color.Green * 255);
}
public static byte GetByteBlue(this Color color)
{
ArgumentNullException.ThrowIfNull(color);
return ToByte(color.Blue * 255);
}
The ToByte method, invoked by several conversion methods, is defined as follows.
static byte ToByte(float input)
{
var clampedInput = Math.Clamp(input, 0, 255);
return (byte)Math.Round(clampedInput);
}
The Math.Clamp method returns a value clamped to the original value including the specified minimum and maximum ranges. The result is rounded via Math.Round and then converted into a byte value.
Tip: In order to use conversion methods, you need the following directive: using CommunityToolkit.Maui.Core.Extensions;
The list of available methods is very long, so a good idea is grouping methods by return type and purpose. Table 9 summarizes methods that return another Color as the result of the conversion or bool as the result of a color check.
Table 9: Methods for Conversion to Color
Method name | Return type | Description |
|---|---|---|
ToBlackOrWhite | Color | Convert the color to the closest monochrome color between Color.Black and Color.White. |
ToBlackOrWhiteForText | Color | If the starting color is determined to be dark for the human eye, convert the color to Color.Black, otherwise to Color.White. |
ToGrayScale | Color | Convert the color to a grayscale color. |
ToInverseColor | Color | Return the inverse color. |
IsDark | bool | Return true if the specified color is determined to be dark. |
IsDarkForTheEye | bool | Return true if the specified color is determined to be dark for the human eye. |
All the methods in Table 9 (except for IsDark and IsDarkForTheEye) work in the same way: they are invoked over a color instance, and they return another Color object. For example, you can easily retrieve the inverse color for the specified Color object as follows.
Color newColor = Colors.Red.ToInverseColor();
In this example, newColor receives zero for red, 1 for green, 1 for blue, and 1 for alpha. Another set of methods is used to retrieve individual components from a color. These methods are summarized in Table 10.
Table 10: Methods that Return Components of a Color
Method name | Return type | Description |
|---|---|---|
GetByteRed | byte | Returns the red component of a color. |
GetByteGreen | byte | Returns the green component of a color. |
GetByteBlue | byte | Returns the blue component of a color. |
GetDegreeHue | double | Returns the hue component of a color, with a value between 0 and 360. |
GetPercentCyan | float | Returns the percentage of cyan in a color, with a value between 0 and 1. |
GetPercentMagenta | float | Returns the percentage of magenta in a color, with a value between 0 and 1. |
GetPercentYellow | float | Returns the percentage of yellow in a color, with a value between 0 and 1. |
GetPercentBlackKey | float | Returns the percentage of the black key in a color, with a value between 0 and 1. |
GetByteAlpha | byte | Returns the alpha-blending component in a color, with a value between 0 and 1. |
Tip: For methods that return byte, the minimum and maximum values are between 0 and 255, which is the range for the byte type.
In the following line of code, you can see how to return a component from a color.
byte blue = Colors.Maroon.GetByteBlue();
The other methods work the same, obviously with their specific return type. Another group of methods returns formatted string objects with color components, as represented in Table 11.
Table 11: Methods for Retrieving Formatted Strings
Method name | Description |
|---|---|
ToCmykaString | Returns a string containing the percentage of cyan, magenta, yellow, black key, and alpha from a color. The alpha value is between 0 and 1. The other values are between 0 and 100. |
ToCmykString | Returns a string containing the percentage of cyan, magenta, yellow, and black key from a color. Values are between 0 and 100. |
ToHslaString | Returns a string containing the amount of hue, saturation, lightness, and alpha from a color. Hue is between 0 and 360, alpha is between 0 and 1, and the others are between 0 and 100. |
ToHslString | Returns a string containing the amount of hue, saturation, and lightness from a color. Hue is between 0 and 360, and the other values are between 0 and 100. |
ToRgbaString | Returns a string containing the red, green, blue, and alpha values from a color. Alpha is between 0 and 1, and the other values are between 0 and 255. |
ToRgbString | Returns a string containing the red, green, and blue values from a color. Values are between 0 and 255. |
Methods in this group also work in the same way. For example, you can retrieve the RGB with alpha components as follows.
Console.WriteLine(Colors.Azure.ToRgbaString());
The result of the invocation is the following.
> RGBA(240,255,255,1)
Tip: Remember that invoking Console.WriteLine in a .NET MAUI project will print the output in the Output window.
The last group of extension methods allow for generating a new Color from an existing one, to which a different component is applied. Table 12 summarizes these methods.
Table 12: Methods for Color Conversion
Method name | Return type | Description |
|---|---|---|
WithRed | Color | Replaces the red component of a color with a value between 0 and 255. |
WithGreen | Color | Replaces the green component of a color with a value between 0 and 255. |
WithBlue | Color | Replaces the blue component of a color with a value between 0 and 255. |
WithCyan | Color | Replaces the cyan component of a color with a value between 0 and 1. |
WithMagenta | Color | Replaces the magenta component of a color with a value between 0 and 1. |
WithYellow | Color | Replaces the yellow component of a color with a value between 0 and 1. |
WithBlackKey | Color | Replaces the black key component of a color with a value between 0 and 1. |
For example, the following code adds the maximum value for the yellow component and creates a derived color.
Color newColor = Colors.PaleVioletRed.WithYellow(1);
Methods for color conversion can be very useful in a variety of scenarios, and the library of methods provided by the .NET MAUI Community Toolkit will cover most of your needs.
The .NET MAUI Community Toolkit also provides interesting extensions to methods that you can use if you work with the dependency injection and inversion of control patterns. Such methods simplify the way you register views and their associated viewmodels within the .NET MAUI IServiceCollection, a type handled by the MauiApp class that registers the services that will be used across the app.
For a better understanding, consider the AddScoped<TView>, AddSingleton<TView>, and AddTransient<TView> methods. These are already part of the MAUI codebase, and they respectively allow for adding a scoped view, a singleton view, and a transient view to the collection of services. However, with the Toolkit extension, you now have the option to also register a viewmodel along with its view, as follows.
builder.Services.AddScoped<HomePage, HomePageViewModel>();
builder.Services.AddSingleton<HomePage, HomePageViewModel>();
builder.Services.AddTransient<HomePage, HomePageViewModel>();
Similarly, there are methods in MAUI that allow for registering a view so that the Shell can navigate to the view via the specified route. These methods are AddScopedWithShellRoute<TView>, AddSingletonWithShellRoute<TView>, and AddTransientWithShellRoute<TView>, and they have the same purpose as the previously mentioned methods, but with the possibility to specify a shell route. With the Community Toolkit, you can now associate a viewmodel as follows.
builder.Services.AddScopedWithShellRoute<HomePage, HomePageViewModel>();
builder.Services.AddSingletonWithShellRoute<HomePage, HomePageViewModel>();
builder.Services.AddTransientWithShellRoute<HomePage, HomePageViewModel>();
Though these extension methods become very useful only with dependency injection and inversion of control scenarios, it is worth mentioning that many MVVM third-party frameworks rely on both patterns. Syncfusion has a very interesting article about dependency injection in MAUI that is a nice supplement to this section.
The .NET MAUI Community Toolkit enhances your development experience with a library of extension methods defined in three public classes. Methods exposed by the ColorAnimationExtensions class allow for animating objects of type Color. Methods exposed by the ColorConversionExtensions class allow for converting Color objects into other colors or other types, depending on the value they retrieve. Methods exposed by the ServiceCollectionExtensions class enhance the way you associate viewmodels with views in a dependency injection scenario. As you have seen, this chapter is mostly based on C# code rather than XAML and this is what you will also see in the next chapter, where you will learn how to leverage fluent C# APIs to define the user interface of your apps.