zoft.MauiExtensions.Core
6.1.0
dotnet add package zoft.MauiExtensions.Core --version 6.1.0
NuGet\Install-Package zoft.MauiExtensions.Core -Version 6.1.0
<PackageReference Include="zoft.MauiExtensions.Core" Version="6.1.0" />
<PackageVersion Include="zoft.MauiExtensions.Core" Version="6.1.0" />
<PackageReference Include="zoft.MauiExtensions.Core" />
paket add zoft.MauiExtensions.Core --version 6.1.0
#r "nuget: zoft.MauiExtensions.Core, 6.1.0"
#:package zoft.MauiExtensions.Core@6.1.0
#addin nuget:?package=zoft.MauiExtensions.Core&version=6.1.0
#tool nuget:?package=zoft.MauiExtensions.Core&version=6.1.0
zoft.MauiExtensions
Set of tools designed to be used in .NET 10 MAUI projects, including Views, ViewModels, Services, Extensions and more...
| Nuget Package | Current Version |
|---|---|
| zoft.MauiExtensions.Core |
!! Sample App !!
I'm currently in the process of deploying a sample app (Android) to demonstrate the capabilities of the package. If you're interested in becoming a tester to allow the app to be published, please add your email in the issue created for this purpose: Sample App Testing
Getting Started
For repository contributions, see development and validation, architecture, and versioning and releases. AI coding assistants should start with AGENTS.md.
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 implementationResourceManagerLocalizationService: Implementation of theILocalizationServiceusing 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
ObservableObjectclass, provides a base implementation of theINotifyPropertyChangedinterface with additional features:IsBusyandIsNotBusyproperties for UI bindingBusyMessageproperty for displaying status messagesDoWorkAsync()methods for awaiting asynchronous work with busy state management- Implements
IDisposablefor proper resource cleanup
ZoftObservableRecipient: Based on the
ObservableRecipientclass, provides messaging capabilities:- Provides the same busy-state and disposal helpers as
ZoftObservableObjectthrough a separate implementation - Built-in messenger functionality for communication between ViewModels
- Automatic message registration and cleanup
Broadcast()method for sending property change messages
- Provides the same busy-state and disposal helpers as
ZoftObservableValidator: Based on the
ObservableValidatorclass, provides validation capabilities:- Provides the same busy-state and disposal helpers as
ZoftObservableObjectthrough a separate implementation - Data annotation validation support
ValidateAllProperties()andClearErrors()methods- Override
OnErrorsChanged()to handle validation state changes - Automatic error collection and management
- Provides the same busy-state and disposal helpers as
</br>
Busy Notification Management
Base models provide methods to await asynchronous work while updating IsBusy and BusyMessage, which can be bound to UI elements such as ActivityIndicator. These helpers do not automatically move work to a background thread or dispatch UI updates to the main thread; explicitly dispatch UI operations when needed.
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(INotifyDataErrorInfo source, ZoftObservableValidator target, DataErrorsChangedEventArgs e)
{
base.OnErrorsChanged(source, target, e);
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:
more info will come...
</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 | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-android36.0 is compatible. net10.0-browser was computed. net10.0-ios was computed. net10.0-ios26.0 is compatible. net10.0-maccatalyst was computed. net10.0-maccatalyst26.0 is compatible. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. net10.0-windows10.0.19041 is compatible. |
-
net10.0
- CommunityToolkit.Mvvm (>= 8.4.2)
- Microsoft.Maui.Controls (>= 10.0.101)
-
net10.0-android36.0
- CommunityToolkit.Mvvm (>= 8.4.2)
- Microsoft.Maui.Controls (>= 10.0.101)
-
net10.0-ios26.0
- CommunityToolkit.Mvvm (>= 8.4.2)
- Microsoft.Maui.Controls (>= 10.0.101)
-
net10.0-maccatalyst26.0
- CommunityToolkit.Mvvm (>= 8.4.2)
- Microsoft.Maui.Controls (>= 10.0.101)
-
net10.0-windows10.0.19041
- CommunityToolkit.Mvvm (>= 8.4.2)
- Microsoft.Maui.Controls (>= 10.0.101)
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 |
|---|---|---|
| 6.1.0 | 564 | 9/16/2026 |
| 6.0.0 | 318 | 5/25/2026 |
| 5.2.0 | 3,576 | 9/8/2025 |
| 5.0.1 | 243 | 8/21/2025 |
| 5.0.0 | 5,379 | 2/18/2025 |
| 4.0.0 | 611 | 9/19/2024 |
| 3.1.0 | 348 | 9/6/2024 |
| 3.0.0 | 14,368 | 12/25/2023 |
| 2.0.2 | 1,065 | 4/13/2023 |
| 2.0.1 | 739 | 4/13/2023 |
| 2.0.0 | 10,397 | 4/6/2023 |
| 1.2.0 | 1,449 | 12/7/2022 |
| 1.1.0 | 881 | 12/6/2022 |
| 1.1.0-pre001 | 729 | 12/6/2022 |
| 1.0.8 | 906 | 12/6/2022 |
| 1.0.7 | 886 | 12/5/2022 |
| 1.0.6 | 922 | 11/28/2022 |
| 1.0.5 | 874 | 11/27/2022 |
| 1.0.4 | 876 | 11/24/2022 |
| 1.0.3 | 946 | 11/24/2022 |
### Changed
- Updated CommunityToolkit.Mvvm to 8.4.2 and Microsoft.Maui.Controls to 10.0.101 in the library and sample.
- Updated MinVer to 8.0.0 and Microsoft.SourceLink.GitHub to 10.0.401; kept SourceLink private to the build.
- Updated the sample's CommunityToolkit.Maui dependency to 15.0.1.
- Renamed the shared build properties file to `Directory.Build.props` for discovery on case-sensitive filesystems and removed the unsupported `MinVerMinimumMajorMinorPatch` property. Package versions remain Git-tag driven.
- Added tool-neutral repository guidance and development, architecture, and versioning documentation; removed Copilot-specific instructions.
- Corrected documentation for asynchronous work, model inheritance, and Android deployment.