MauiPersianToolkit is a .NET MAUI UI toolkit for Persian / RTL apps: calendars, inputs, pickers, dialogs, and theming — with native popups, light/dark themes, and built-in fa / en / ar chrome strings. No CommunityToolkit dependency.
DatePicker with Single / Multiple / Range via CalendarOptionsDatePickerView or popup field (popup content is created lazily on first open)ICalendarService + unit tests| Area | Controls |
|——|———-|
| Inputs | EntryView, EditorView, LabelView, CheckBoxView, ButtonView, ToggleButton |
| Suggest | AutoCompleteView (+ native suggest on Android/Windows via PersianAutoSuggest) |
| Pickers | PickerView (single/multi), DatePicker, TimePicker (24h / 12h + seconds) |
| Layout | TabView, ContainerView, Expander, SlideButton, CircleImageView |
| Data | TreeView (virtualized rows, none/single/multi) |
*Async APIs on IDialogServicePopup host API — no third-party popup packageAppTheme (system / light / dark)Pdt* tokens + AppThemeBindingUseMauiPersianToolkit, App.xaml, or PersianTheme.ConfigurePersianToolkitStrings / PersianToolkitStringId for chrome (Accept, Today, SelectTime, …)AdditionalCatalogs; XAML {mpt:Localize Today}Loadednet10.0, Android, iOS, WindowsMicrosoft.Maui.Controls onlyPersianUISamples — categorized gallery with theme + language switcherInstall-Package MauiPersianToolkit
dotnet add package MauiPersianToolkit
MauiProgram.csbuilder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
})
.UseMauiPersianToolkit(options =>
{
options.DefaultCalendarType = CalendarType.Persian;
options.Localization.Culture = "fa"; // fa | en | ar
// Optional theme overrides
// options.Theme.Accent = Colors.Teal;
});
Fonts (IranianSans, FontAwesome), handlers, dialog service, and theme defaults are registered for you.
App.xaml (recommended)<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:persian="clr-namespace:MauiPersianToolkit.Resources;assembly=MauiPersianToolkit"
x:Class="YourApp.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<persian:PersianStyles/>
</ResourceDictionary.MergedDictionaries>
<!-- Optional overrides after merge -->
<!-- <Color x:Key="PdtAccent">#2DD4BF</Color> -->
</ResourceDictionary>
</Application.Resources>
</Application>
If you skip merging, UseMauiPersianToolkit still injects defaults when the app or first control starts. You can also call PersianTheme.EnsureApplicationStyles() early in App.
xmlns:pui="clr-namespace:MauiPersianToolkit.Controls;assembly=MauiPersianToolkit"
xmlns:mpt="http://schemas.mauipersiantoolkit.com/2026/toolkit"
DatePicker (calendar type & selection live on CalendarOptions):
<pui:DatePicker PlaceHolder="تاریخ"
DisplayFormat="yyyy/MM/dd"
Icon=""
SelectedPersianDate="{Binding SelectedDate}"
CalendarOption="{Binding CalendarOption}"/>
public CalendarOptions CalendarOption { get; } = new()
{
CalendarType = CalendarType.Persian, // or Gregorian / Hijri
SelectionMode = SelectionMode.Single, // Single | Multiple | Range
AutoCloseAfterSelectDate = true,
SelectDayColor = Color.FromArgb("#5B2BDF"),
};
TimePicker:
<pui:TimePicker PlaceHolder="ساعت جلسه"
SelectedTime="{Binding MeetingTime}"
DisplayFormat="HH:mm"
Is24Hour="True"
MinuteInterval="5"/>
AutoCompleteView:
<pui:AutoCompleteView PlaceHolder="شهر"
ItemsSource="{Binding Cities}"
DisplayProperty="Title"
Text="{Binding CityText}"
SelectedItem="{Binding SelectedCity}"
Options="{Binding CityOptions}"/>
public AutoCompleteOptions CityOptions { get; } = new()
{
FilterMode = AutoCompleteFilterMode.Contains,
MinimumPrefixLength = 1,
MaxSuggestions = 8,
UseNativeSuggestions = true,
ShowClearButton = true,
OpenOnFocus = true,
};
Inputs / layout:
<pui:EntryView PlaceHolder="نام" Icon="" Text="{Binding Name}"/>
<pui:EditorView Title="شرح" PlaceHolder="متن…" Text="{Binding Notes}"/>
<pui:PickerView PlaceHolder="انتخاب" ItemsSource="{Binding Items}"
DisplayProperty="Title" SelectionMode="Single"/>
<pui:TabView SelectedTabColor="{StaticResource PdtAccent}">
<pui:TabView.ItemsSource>
<pui:TabItemView Title="اول" Icon="">…</pui:TabItemView>
<pui:TabItemView Title="دوم" Icon="">…</pui:TabItemView>
</pui:TabView.ItemsSource>
</pui:TabView>
<pui:Expander IsExpanded="False">
<pui:Expander.Header>
<Label Text="Header" FontFamily="IranianSans"/>
</pui:Expander.Header>
<Label Text="Body"/>
</pui:Expander>
var persian = CalendarServiceFactory.GetService(CalendarType.Persian);
string date = persian.ToCalendarDate(DateTime.Now); // e.g. 1403/…
DateTime g = persian.ToGregorianDate("1403/05/25");
DateTime.Now.ToPersianDate();
DateTime.Now.ToCalendarDate(CalendarType.Hijri);
"1403/05/25".ToDateTime();
Custom calendars: implement ICalendarService and register with CalendarServiceFactory.RegisterService(...).
IDialogService)Registered as a singleton by UseMauiPersianToolkit. Prefer async APIs when you need a result:
await dialogs.AlertAsync("پیام", "عنوان");
bool ok = await dialogs.ConfirmAsync(new ConfirmConfig
{
Title = "حذف",
Message = "ادامه میدهید؟",
Icon = MessageIcon.QUESTION,
});
PromptResult prompt = await dialogs.PromptAsync(new PromptConfig
{
Title = "نام",
Placeholder = "…",
});
dialogs.Toast(new ToastConfig { Message = "ذخیره شد" });
dialogs.Snackbar(new SnackbarConfig
{
Message = "حذف شد",
AcceptText = "بازگردانی",
Duration = TimeSpan.FromSeconds(5),
});
await Toast.Make("Saved", ToastDuration.Short).Show();
await Snackbar.Make("Deleted", () => { /* undo */ }, "Undo", TimeSpan.FromSeconds(3)).Show();
| Key | Role |
|---|---|
PdtPageLight / PdtPageDark |
Page background |
PdtSurfaceLight / PdtSurfaceDark |
Cards, dialogs, containers |
PdtInputFillLight / PdtInputFillDark |
Input fill |
PdtOutlineLight / PdtOutlineDark |
Borders |
PdtOnSurfaceLight / PdtOnSurfaceDark |
Primary text |
PdtMutedLight / PdtMutedDark |
Secondary text |
PdtFooterLight / PdtFooterDark |
Dialog footers |
PdtDisabledLight / PdtDisabledDark |
Disabled |
PdtDayButtonLight / PdtDayButtonDark |
Calendar day cells |
PdtAccept / PdtCancel / PdtAccent |
Actions |
PdtAlertBg* / PdtAlertFg* |
Toast / snackbar |
Constants: PersianThemeKeys. Defaults: PersianStyles.
PersianTheme.Configure(theme =>
{
theme.SurfaceDark = Color.FromArgb("#111827");
theme.Accent = Colors.Orange;
});
Built-in: fa, en, ar.
builder.UseMauiPersianToolkit(options =>
{
options.Localization.Culture = "ar";
options.Localization.StringOverrides[PersianToolkitStringId.Ok] = "متوجه شدم";
});
// Runtime
PersianToolkitStrings.SetCulture("en");
| Key | fa | en | ar |
|---|---|---|---|
Accept |
ثبت | Save | حفظ |
Cancel |
انصراف | Cancel | إلغاء |
Confirm |
تایید | OK | تأكيد |
Ok |
باشه | OK | حسناً |
SelectDate |
انتخاب تاریخ | Select date | اختر التاريخ |
SelectTime |
انتخاب زمان | Select time | اختر الوقت |
Today |
امروز | Today | اليوم |
Now |
الان | Now | الآن |
XAML: {mpt:Localize Today}. After a runtime culture change, recreate or navigate back to the page so bindings refresh.
PersianUISamples)Full gallery of every control, grouped by category:
Run:
dotnet build ./PersianUISamples/PersianUISamples.csproj -f net10.0-android
dotnet test ./MauiPersianToolkit.Test/MauiPersianToolkit.Test.csproj
Coverage includes calendar conversion, week layout, Hijri display, localization, AutoComplete filtering, TimePicker, dialogs, expander, tree flatten, and popup options.
MIT — see LICENSE.
| Area | Status |
|---|---|
| Core / .NET 10 | Stable |
| Calendars (fa / en / Hijri) | Stable |
| Inputs, pickers, tabs, tree | Stable |
| AutoComplete + TimePicker | Stable |
| Native popup / toast / snackbar | Stable |
Theme (Pdt*) |
Stable |
| Localization fa / en / ar | Stable |
| Sample gallery | Updated |
| Unit tests + CI | Active |