zoft.MauiExtensions.Core
5.0.1
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
<PackageReference Include="zoft.MauiExtensions.Core" Version="5.0.1" />
<PackageVersion Include="zoft.MauiExtensions.Core" Version="5.0.1" />
<PackageReference Include="zoft.MauiExtensions.Core" />
paket add zoft.MauiExtensions.Core --version 5.0.1
#r "nuget: zoft.MauiExtensions.Core, 5.0.1"
#:package zoft.MauiExtensions.Core@5.0.1
#addin nuget:?package=zoft.MauiExtensions.Core&version=5.0.1
#tool nuget:?package=zoft.MauiExtensions.Core&version=5.0.1
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 |
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 implementationResourceManagerLocalizationService
: Implementation of theILocalizationService
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 theINotifyPropertyChanged
interface with additional features:IsBusy
andIsNotBusy
properties for UI bindingBusyMessage
property for displaying status messagesDoWorkAsync()
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
- Inherits all features from
ZoftObservableValidator: Based on the
ObservableValidator
class, provides validation capabilities:- All features of
ZoftObservableObject
- Data annotation validation support
ValidateAllProperties()
andClearErrors()
methods- Override
OnErrorsChanged()
to handle validation state changes - Automatic error collection and management
- All features of
</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 | Versions 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. |
-
net9.0
- CommunityToolkit.Mvvm (>= 8.4.0)
- Microsoft.Maui.Controls (>= 9.0.100)
- Microsoft.SourceLink.GitHub (>= 8.0.0)
-
net9.0-android35.0
- CommunityToolkit.Mvvm (>= 8.4.0)
- Microsoft.Maui.Controls (>= 9.0.100)
- Microsoft.SourceLink.GitHub (>= 8.0.0)
-
net9.0-ios18.0
- CommunityToolkit.Mvvm (>= 8.4.0)
- Microsoft.Maui.Controls (>= 9.0.100)
- Microsoft.SourceLink.GitHub (>= 8.0.0)
-
net9.0-maccatalyst18.0
- CommunityToolkit.Mvvm (>= 8.4.0)
- Microsoft.Maui.Controls (>= 9.0.100)
- Microsoft.SourceLink.GitHub (>= 8.0.0)
-
net9.0-windows10.0.19041
- CommunityToolkit.Mvvm (>= 8.4.0)
- Microsoft.Maui.Controls (>= 9.0.100)
- Microsoft.SourceLink.GitHub (>= 8.0.0)
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.