zoft.MauiExtensions.Core 5.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package zoft.MauiExtensions.Core --version 5.0.1
                    
NuGet\Install-Package zoft.MauiExtensions.Core -Version 5.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="zoft.MauiExtensions.Core" Version="5.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="zoft.MauiExtensions.Core" Version="5.0.1" />
                    
Directory.Packages.props
<PackageReference Include="zoft.MauiExtensions.Core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add zoft.MauiExtensions.Core --version 5.0.1
                    
#r "nuget: zoft.MauiExtensions.Core, 5.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package zoft.MauiExtensions.Core@5.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=zoft.MauiExtensions.Core&version=5.0.1
                    
Install as a Cake Addin
#tool nuget:?package=zoft.MauiExtensions.Core&version=5.0.1
                    
Install as a Cake Tool

zoft.MauiExtensions

Set of tools designed to be used in MAUI projects, including Views, ViewModels, Services, Extensions and more...

Nuget Package Current Version
zoft.MauiExtensions.Core NuGet

Getting Started

Install nuget package: zoft.MauiExtensions.Core

Install-Package zoft.MauiExtensions.Core

How To Use

Refer to the sample to have a better understanding of package capabilities. Bellow you can find the most common features and how to use them

</br>

Localization Service

The package provides a set of tools to implement localization in your app:

  • ILocalizationService: Interface for the localization service. The interface exists to make it easier to use iwith IOC and to override the base implementation
  • ResourceManagerLocalizationService: Implementation of the ILocalizationService using resource files (.resx)
builder.Services.AddSingleton<ILocalizationService>(new ResourceManagerLocalizationService(AppResources.ResourceManager, SupportedLanguages.DefaultLanguage));
  • TranslationMarkup: XAML markup that provides an easy way to apply the translation directly in XAML
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:zoft="http://zoft.maui.extensions"
             x:Class="zoft.MauiExtensions.Sample.Views.LocalizationView"
             Title="{zoft:Translate LocalizationPage_Title}">
    ...
    ...
    <ScrollView>
        <VerticalStackLayout Spacing="10">
            <Label Text="{zoft:Translate LocalizationPage_Label1}" FontSize="16" FontAttributes="Bold"/>
            <Label Text="{zoft:Translate LocalizationPage_Label2}" />
            <Label Text="{zoft:Translate LocalizationPage_Label3}" FontAttributes="Italic" BackgroundColor="LightGray"/>
        </VerticalStackLayout>
    </ScrollView>
    ...
</ContentPage>

</br>

Base Models

Based on the Component Models of the CommunityToolkit.MVVM, the package provides a set of base models that can be used to create Models, ViewModels and Services in your app.

  • ZoftObservableObject: Based on the ObservableObject class, provides a base implementation of the INotifyPropertyChanged interface with additional features:

    • IsBusy and IsNotBusy properties for UI binding
    • BusyMessage property for displaying status messages
    • DoWorkAsync() methods for executing background tasks with busy state management
    • Implements IDisposable for proper resource cleanup
  • ZoftObservableRecipient: Based on the ObservableRecipient class, provides messaging capabilities:

    • Inherits all features from ZoftObservableObject
    • Built-in messenger functionality for communication between ViewModels
    • Automatic message registration and cleanup
    • Broadcast() method for sending property change messages
  • ZoftObservableValidator: Based on the ObservableValidator class, provides validation capabilities:

    • All features of ZoftObservableObject
    • Data annotation validation support
    • ValidateAllProperties() and ClearErrors() methods
    • Override OnErrorsChanged() to handle validation state changes
    • Automatic error collection and management

</br>

Busy Notification Management

Base models provide methods to execute code in a background thread, while providing with updated on IsBusy and BusyMessage properties that can be bound to an UI element (i.e. ActivityIndicator)

await DoWorkAsync(() => ..., "Busy Message");

var result = await DoWorkAsync(() => return some_object, "BusyMessage");

</br>

Validation

The ZoftObservableValidator base class provides comprehensive validation capabilities using data annotations:

public partial class ValidationViewModel : ZoftObservableValidator
{
    [ObservableProperty]
    [Required]
    [MinLength(2)]
    [MaxLength(100)]
    public partial string FirstName { get; set; }

    [ObservableProperty]
    [Required]
    [EmailAddress]
    public partial string Email { get; set; }

    protected override void OnErrorsChanged(object sender, DataErrorsChangedEventArgs e)
    {
        base.OnErrorsChanged(sender, e);
        
        // Handle validation state changes
        ErrorMessage = string.Join(Environment.NewLine, GetErrors().Select(e => e.ErrorMessage));
    }

    [RelayCommand]
    private void Validate()
    {
        ValidateAllProperties();
    }

    [RelayCommand]
    private void ClearValidation()
    {
        ClearErrors();
    }
}

</br>

Messenger and Communication

The ZoftObservableRecipient base class provides built-in messaging capabilities for ViewModel communication:

public partial class MessengerViewModel : ZoftObservableRecipient, 
    IRecipient<PropertyChangedMessage<string>>, 
    IRecipient<CustomMessage>
{
    public MessengerViewModel() : base()
    {
        IsActive = true; // Enable message reception
    }

    // Receive property change messages
    void IRecipient<PropertyChangedMessage<string>>.Receive(PropertyChangedMessage<string> message)
    {
        if (message.PropertyName == nameof(Text))
            Text = message.NewValue;
    }

    // Receive custom messages
    void IRecipient<CustomMessage>.Receive(CustomMessage message)
    {
        // Handle custom message
    }

    [RelayCommand]
    private void SendMessage()
    {
        // Broadcast property changes
        Broadcast(oldValue, newValue, nameof(PropertyName));
        
        // Send custom messages
        Messenger.Send<CustomMessage>();
    }
}

</br>

Weak Subscription

The package provides a set of extension methods to subscribe to events using weak references, avoiding memory leaks when the subscriber is not disposed properly:

// Subscribe to PropertyChanged events
INotifyPropertyChanged source = someObject;
var subscription = source.WeakSubscribe((sender, e) => 
{
    // Handle property change
    Console.WriteLine($"Property {e.PropertyName} changed");
});

// Subscribe to CollectionChanged events
INotifyCollectionChanged collection = observableCollection;
var collectionSubscription = collection.WeakSubscribe((sender, e) => 
{
    // Handle collection change
    Console.WriteLine($"Collection changed: {e.Action}");
});

// Subscribe to generic events
var eventSubscription = someObject.WeakSubscribe("SomeEvent", (sender, e) => 
{
    // Handle generic event
});

// Subscribe to events with custom event args
var customSubscription = someObject.WeakSubscribe<CustomEventArgs>("CustomEvent", (sender, e) => 
{
    // Handle custom event
});

// Dispose subscriptions when no longer needed
subscription.Dispose();
collectionSubscription.Dispose();
eventSubscription.Dispose();
customSubscription.Dispose();

</br>

Extensions

The library provides numerous extension methods to simplify common operations:

Collection Extensions
// Add missing items to a collection
targetCollection.AddMissing(itemsToAdd);
targetCollection.AddMissing(itemsToAdd, customValidationFunc);

// Safe count with fallback
int count = collection.Count(fallbackValue: 0);
String Extensions
// Null-safe string operations
bool isEmpty = text.IsNullOrEmpty();
bool isWhitespace = text.IsNullOrWhiteSpace();

// Template formatting with null safety
string result = template.FormatTemplate(arg1, arg2);

// Regular expression matching
bool matches = input.IsMatch(@"\d+");
string extract = input.Extract(@"(\d+)");
DateTime Extensions
// Null-safe formatting
string formatted = nullableDate.Format("yyyy-MM-dd");

// Date operations
DateTime dateOnly = dateTime.ToDate();
string shortDate = dateTime.ToShortDateString();
DateTime utcAdjusted = dateTime.GetUtcAdjustedTime();
Object Extensions
// Reflection-based property access
object value = obj.GetPropertyValue("PropertyName");
string stringValue = obj.GetPropertyValueAsString("PropertyName", "default");
obj.SetPropertyValue("PropertyName", newValue);

// Null checking
var nonNull = obj.ThrowIfNull(nameof(obj));
Task Extensions
// Timeout support
var result = await task.WithTimeout(5000); // 5 seconds
var result = await task.WithTimeout(TimeSpan.FromMinutes(1));

// Safe fire-and-forget execution
task.SafeFireAndForget(onException: ex => Console.WriteLine(ex.Message));
List Extensions
// Find index with predicate
int index = list.FindIndex(item => item.Name == "test");

// Apply action to all items
list.ForEach(item => item.Process());
Dictionary Extensions
// Safe operations
dictionary.AddOrUpdate(key, value);
dictionary.AddOrUpdate(keyValuePairs); // Bulk operations
dictionary.AddOrIgnore(keyValuePairs); // Add only if key doesn't exist
dictionary.RemoveIfExists(key);

// Apply action to all items
dictionary.ForEach((key, value) => Console.WriteLine($"{key}: {value}"));

// Convert to tuple list
var tuples = dictionary.ToTupleList();
Exception Extensions
// Get full exception description including inner exceptions
string fullDescription = exception.GetFullDescription();
Type Extensions
// Get properties with various options
var publicProps = type.GetProperties(onlyPublic: true);
var allProps = type.GetProperties(onlyPublic: false, includeInherited: true);
Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-android35.0 is compatible.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-ios18.0 is compatible.  net9.0-maccatalyst was computed.  net9.0-maccatalyst18.0 is compatible.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net9.0-windows10.0.19041 is compatible.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on zoft.MauiExtensions.Core:

Package Downloads
zoft.MauiExtensions.Controls.AutoCompleteEntry

.Net MAUI Entry control that provides a list of suggestions as the user types.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
5.2.0 0 9/8/2025
5.0.1 127 8/21/2025
5.0.0 1,250 2/18/2025
4.0.0 469 9/19/2024
3.1.0 216 9/6/2024
3.0.0 9,987 12/25/2023
2.0.2 946 4/13/2023
2.0.1 596 4/13/2023
2.0.0 8,065 4/6/2023
1.2.0 1,264 12/7/2022
1.1.0 769 12/6/2022
1.1.0-pre001 590 12/6/2022
1.0.8 766 12/6/2022
1.0.7 765 12/5/2022
1.0.6 804 11/28/2022
1.0.5 737 11/27/2022
1.0.4 744 11/24/2022
1.0.3 813 11/24/2022
1.0.2 764 11/7/2022
1.0.1 859 10/20/2022
1.0.0 850 8/29/2022
1.0.0-RC1 194 5/6/2022
1.0.0-alfa.4 228 10/11/2021
1.0.0-alfa.3 229 9/22/2021
1.0.0-alfa.2 279 7/15/2021
1.0.0-alfa.1 280 6/24/2021

Fixed MVVMTK0045 warnings by adding missing partial methods.
Updated NuGet package references.