![]() |
VOOZH | about |
dotnet add package I-Synergy.Framework.UI.Maui --version 2026.10618.11733
NuGet\Install-Package I-Synergy.Framework.UI.Maui -Version 2026.10618.11733
<PackageReference Include="I-Synergy.Framework.UI.Maui" Version="2026.10618.11733" />
<PackageVersion Include="I-Synergy.Framework.UI.Maui" Version="2026.10618.11733" />Directory.Packages.props
<PackageReference Include="I-Synergy.Framework.UI.Maui" />Project file
paket add I-Synergy.Framework.UI.Maui --version 2026.10618.11733
#r "nuget: I-Synergy.Framework.UI.Maui, 2026.10618.11733"
#:package I-Synergy.Framework.UI.Maui@2026.10618.11733
#addin nuget:?package=I-Synergy.Framework.UI.Maui&version=2026.10618.11733Install as a Cake Addin
#tool nuget:?package=I-Synergy.Framework.UI.Maui&version=2026.10618.11733Install as a Cake Tool
Cross-platform .NET MAUI UI framework for building modern applications on Windows, Android, iOS, and macOS. This package provides a complete MAUI implementation of the I-Synergy Framework UI services, controls, and patterns.
👁 NuGet
👁 License
👁 .NET
👁 Platforms
Install the package via NuGet:
dotnet add package I-Synergy.Framework.UI.Maui
Setup your MAUI application with I-Synergy Framework services:
using ISynergy.Framework.UI.Extensions;
using Microsoft.Extensions.Logging;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureLogging((appBuilder, logging) =>
{
#if DEBUG
logging.AddDebug();
logging.SetMinimumLevel(LogLevel.Trace);
#endif
})
.ConfigureServices<App, AppContext, CommonServices, SettingsService, Resources>(
appBuilder =>
{
// Register additional services here
appBuilder.Services.AddScoped<IProductService, ProductService>();
appBuilder.Services.AddTransient<MainViewModel>();
},
Assembly.GetExecutingAssembly(),
assemblyName => assemblyName.Name.StartsWith("MyApp")
);
return builder.Build();
}
}
<?xml version="1.0" encoding="utf-8" ?>
<ui:View xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ui="clr-namespace:ISynergy.Framework.UI.Controls;assembly=ISynergy.Framework.UI.Maui"
xmlns:vm="clr-namespace:MyApp.ViewModels"
x:Class="MyApp.Views.ProductListView"
x:DataType="vm:ProductListViewModel"
Title="{Binding Title}">
<Grid RowDefinitions="Auto,*">
<HorizontalStackLayout Grid.Row="0" Padding="10">
<Button Text="Add Product"
Command="{Binding AddProductCommand}" />
<Button Text="Refresh"
Command="{Binding RefreshCommand}" />
</HorizontalStackLayout>
<CollectionView Grid.Row="1"
ItemsSource="{Binding Products}"
SelectionMode="Single"
SelectedItem="{Binding SelectedProduct}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}"
FontSize="16"
FontAttributes="Bold" />
<Label Grid.Column="1"
Text="{Binding Price, StringFormat='{0:C}'}"
VerticalOptions="Center" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</ui:View>
using ISynergy.Framework.Mvvm.ViewModels;
public partial class ProductListView : View
{
public ProductListView()
{
InitializeComponent();
}
}
The MAUI dialog service provides comprehensive error handling and fallback mechanisms:
using ISynergy.Framework.Mvvm.ViewModels;
using ISynergy.Framework.Mvvm.Commands;
public class ProductListViewModel : ViewModelNavigation<Product>
{
private readonly IProductService _productService;
public ObservableCollection<Product> Products { get; } = new();
public AsyncRelayCommand AddProductCommand { get; }
public AsyncRelayCommand RefreshCommand { get; }
public AsyncRelayCommand<Product> DeleteProductCommand { get; }
public ProductListViewModel(
ICommonServices commonServices,
IProductService productService,
ILogger<ProductListViewModel> logger)
: base(commonServices, logger)
{
_productService = productService;
Title = "Products";
AddProductCommand = new AsyncRelayCommand(AddProductAsync);
RefreshCommand = new AsyncRelayCommand(RefreshAsync);
DeleteProductCommand = new AsyncRelayCommand<Product>(DeleteProductAsync);
}
public override async Task InitializeAsync()
{
await base.InitializeAsync();
await RefreshAsync();
IsInitialized = true;
}
private async Task AddProductAsync()
{
await CommonServices.DialogService
.ShowDialogAsync<ProductEditWindow, ProductEditViewModel, Product>();
await RefreshAsync();
}
private async Task RefreshAsync()
{
try
{
CommonServices.BusyService.StartBusy("Loading products...");
var products = await _productService.GetAllAsync();
Products.Clear();
foreach (var product in products)
{
Products.Add(product);
}
}
catch (Exception ex)
{
await CommonServices.DialogService.ShowErrorAsync(ex, "Error");
}
finally
{
CommonServices.BusyService.StopBusy();
}
}
private async Task DeleteProductAsync(Product product)
{
var result = await CommonServices.DialogService.ShowMessageAsync(
$"Are you sure you want to delete {product.Name}?",
"Confirm Delete",
MessageBoxButtons.YesNo);
if (result == MessageBoxResult.Yes)
{
try
{
await _productService.DeleteAsync(product.Id);
Products.Remove(product);
await CommonServices.DialogService.ShowInformationAsync(
"Product deleted successfully",
"Success");
}
catch (Exception ex)
{
await CommonServices.DialogService.ShowErrorAsync(ex, "Error");
}
}
}
}
Navigate between pages using the navigation service:
using ISynergy.Framework.Mvvm.Abstractions.Services;
public class MainViewModel : ViewModel
{
private readonly INavigationService _navigationService;
public AsyncRelayCommand NavigateToProductsCommand { get; }
public AsyncRelayCommand NavigateToSettingsCommand { get; }
public MainViewModel(
ICommonServices commonServices,
INavigationService navigationService,
ILogger<MainViewModel> logger)
: base(commonServices, logger)
{
_navigationService = navigationService;
NavigateToProductsCommand = new AsyncRelayCommand(NavigateToProductsAsync);
NavigateToSettingsCommand = new AsyncRelayCommand(NavigateToSettingsAsync);
}
private async Task NavigateToProductsAsync()
{
await _navigationService.NavigateAsync<ProductListViewModel>();
}
private async Task NavigateToSettingsAsync()
{
await _navigationService.NavigateAsync<SettingsViewModel>();
}
// Navigate with parameters
private async Task NavigateToProductDetailAsync(Product product)
{
await _navigationService.NavigateAsync<ProductDetailViewModel>(product);
}
// Modal navigation
private async Task ShowModalAsync()
{
await _navigationService.NavigateModalAsync<ModalViewModel>();
}
}
Apply dynamic themes with custom accent colors:
using ISynergy.Framework.Mvvm.Abstractions.Services;
using ISynergy.Framework.Core.Enumerations;
// Theme service is automatically configured during startup
// It reads theme preferences from ISettingsService
// To show theme selection to users:
public class SettingsViewModel : ViewModel
{
public AsyncRelayCommand ChangeThemeCommand { get; }
public SettingsViewModel(
ICommonServices commonServices,
ILogger<SettingsViewModel> logger)
: base(commonServices, logger)
{
ChangeThemeCommand = new AsyncRelayCommand(ChangeThemeAsync);
}
private async Task ChangeThemeAsync()
{
await CommonServices.DialogService
.ShowDialogAsync<ThemeWindow, ThemeViewModel, ThemeStyle>();
}
}
The theme service supports:
<ui:NavigationMenu ItemsSource="{Binding MenuItems}"
SelectedItem="{Binding SelectedMenuItem}"
IsExpanded="{Binding IsMenuExpanded}" />
<controls:ImageBrowser Images="{Binding ProductImages}"
SelectedImage="{Binding SelectedImage}"
AllowAdd="True"
AllowRemove="True" />
<controls:ErrorPresenter Errors="{Binding ValidationErrors}"
IsVisible="{Binding HasErrors}" />
<ui:TabbedView>
<ui:TabbedView.Items>
<TabViewItem Title="General">
<local:GeneralSettingsView />
</TabViewItem>
<TabViewItem Title="Security">
<local:SecuritySettingsView />
</TabViewItem>
</ui:TabbedView.Items>
</ui:TabbedView>
The MAUI framework provides Windows-specific extensions:
// In Platforms/Windows folder
using ISynergy.Framework.UI.Platforms.Windows.Extensions;
// Customize app window
var window = GetAppWindow();
window.SetIcon("Assets/icon.ico");
window.SetTitle("My Application");
// Apply theme colors to title bar
_themeService.ApplyTheme(); // Automatically updates title bar
Theme colors are automatically applied to Android status bar and action bar.
Native navigation bar and status bar colors are synchronized with theme.
The MAUI framework includes 20+ value converters:
<Label IsVisible="{Binding IsActive, Converter={StaticResource BoolToVisibilityConverter}}" />
<Label Text="{Binding IsEnabled, Converter={StaticResource BoolToYesNoConverter}}" />
<Label Text="{Binding Amount, Converter={StaticResource DecimalToCurrencyConverter}}" />
<Label Text="{Binding Quantity, Converter={StaticResource IntegerToStringConverter}}" />
<Label Text="{Binding CreatedDate, Converter={StaticResource DateTimeToStringConverter}}" />
<Label Text="{Binding UpdatedDate, Converter={StaticResource DateTimeOffsetToLocalStringConverter}}" />
<Label IsVisible="{Binding Name, Converter={StaticResource StringNullOrEmptyToBoolConverter}}" />
<Label Text="{Binding Description, Converter={StaticResource StringToUpperConverter}}" />
<Label IsVisible="{Binding Items, Converter={StaticResource CollectionNullOrEmptyToBoolConverter}}" />
<Label Text="{Binding Items, Converter={StaticResource CollectionCountConverter}}" />
<BoxView Color="{Binding HexColor, Converter={StaticResource StringToColorConverter}}" />
<Picker ItemsSource="{Binding Source={StaticResource OrderStatusEnum}}"
SelectedItem="{Binding Status, Converter={StaticResource EnumToStringConverter}}" />
<Label Text="{Binding Id, Converter={StaticResource GuidToStringConverter}}" />
using ISynergy.Framework.Mvvm.Abstractions.Services;
using ISynergy.Framework.Core.Models.Results;
public class DocumentViewModel : ViewModel
{
private readonly IFileService<FileResult> _fileService;
public DocumentViewModel(
ICommonServices commonServices,
IFileService<FileResult> fileService,
ILogger<DocumentViewModel> logger)
: base(commonServices, logger)
{
_fileService = fileService;
OpenFileCommand = new AsyncRelayCommand(OpenFileAsync);
SaveFileCommand = new AsyncRelayCommand(SaveFileAsync);
}
public AsyncRelayCommand OpenFileCommand { get; }
public AsyncRelayCommand SaveFileCommand { get; }
private async Task OpenFileAsync()
{
var file = await _fileService.BrowseFileAsync(
new[] { ".pdf", ".docx", ".txt" });
if (file is not null)
{
// Read file content
using var stream = await file.OpenReadAsync();
// Process file...
}
}
private async Task SaveFileAsync()
{
var file = await _fileService.SaveFileAsync(
"document.pdf",
"Documents",
new[] { ".pdf" });
if (file is not null)
{
// Write file content
using var stream = await file.OpenWriteAsync();
// Save content...
}
}
}
using ISynergy.Framework.Mvvm.Abstractions.Services;
public class ProfileViewModel : ViewModel
{
private readonly ICameraService _cameraService;
public AsyncRelayCommand TakePhotoCommand { get; }
public AsyncRelayCommand PickPhotoCommand { get; }
public ImageSource ProfileImage
{
get => GetValue<ImageSource>();
set => SetValue(value);
}
public ProfileViewModel(
ICommonServices commonServices,
ICameraService cameraService,
ILogger<ProfileViewModel> logger)
: base(commonServices, logger)
{
_cameraService = cameraService;
TakePhotoCommand = new AsyncRelayCommand(TakePhotoAsync);
PickPhotoCommand = new AsyncRelayCommand(PickPhotoAsync);
}
private async Task TakePhotoAsync()
{
var photo = await _cameraService.TakePhotoAsync();
if (photo is not null)
{
ProfileImage = ImageSource.FromStream(() => photo.OpenReadAsync().Result);
}
}
private async Task PickPhotoAsync()
{
var photo = await _cameraService.PickPhotoAsync();
if (photo is not null)
{
ProfileImage = ImageSource.FromStream(() => photo.OpenReadAsync().Result);
}
}
}
<Entry Text="{Binding SearchText}">
<Entry.Behaviors>
<behaviors:SelectAllOnFocusBehavior />
</Entry.Behaviors>
</Entry>
Configure optional application features:
{
"ApplicationFeatures": {
"EnableAnalytics": true,
"EnableCrashReporting": true,
"EnableNotifications": true
},
"ClientApplicationOptions": {
"ApplicationName": "My Application",
"BaseUrl": "https://api.myapp.com",
"ApiVersion": "v1"
}
}
The framework automatically configures multiple fonts:
Use NavigateAsync for standard navigation and NavigateModalAsync for dialogs and overlays.
Always dispose ViewModels and unsubscribe from events in the Cleanup method to prevent memory leaks.
The dialog service implements circuit breaker pattern with automatic fallback to console/debug output if UI is not available.
NavigateAsync<TViewModel>() for page navigationNavigateModalAsync<TViewModel>() for modalsInitializeAsync() after navigation completesOnNavigatedFrom()For more information about the I-Synergy Framework:
For issues, questions, or contributions, please visit the GitHub repository.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0-android36.0 net10.0-android36.0 is compatible. net10.0-ios26.0 net10.0-ios26.0 is compatible. net10.0-maccatalyst26.0 net10.0-maccatalyst26.0 is compatible. net10.0-windows10.0.26100 net10.0-windows10.0.26100 is compatible. |
Showing the top 1 NuGet packages that depend on I-Synergy.Framework.UI.Maui:
| Package | Downloads |
|---|---|
|
I-Synergy.Framework.Synchronization.Maui
I-Synergy Synchronization Client Framework for .Net Maui |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2026.10618.11733 | 0 | 6/18/2026 |
| 2026.10618.11702-preview | 0 | 6/18/2026 |
| 2026.10616.12121 | 72 | 6/16/2026 |
| 2026.10616.11904-preview | 52 | 6/16/2026 |
| 2026.10616.10010 | 65 | 6/15/2026 |
| 2026.10615.12240-preview | 57 | 6/15/2026 |
| 2026.10615.10047-preview | 58 | 6/14/2026 |
| 2026.10614.10112-preview | 52 | 6/13/2026 |
| 2026.10612.12341-preview | 62 | 6/12/2026 |
| 2026.10612.12110-preview | 57 | 6/12/2026 |
| 2026.10612.11941-preview | 59 | 6/12/2026 |
| 2026.10610.10831 | 88 | 6/10/2026 |
| 2026.10610.10706-preview-pr... | 85 | 6/10/2026 |
| 2026.10609.11323-preview | 90 | 6/9/2026 |
| 2026.10607.11905-preview | 90 | 6/7/2026 |
| 2026.10607.11454-preview | 92 | 6/7/2026 |
| 2026.10606.11854-preview | 90 | 6/6/2026 |
| 2026.10603.11238-preview | 89 | 6/3/2026 |
| 2026.10602.12203-preview | 90 | 6/2/2026 |
| 2026.10602.11949-preview | 90 | 6/2/2026 |