Офіційна Fluent тема від Microsoft (PresentationFramework.Fluent) надає базові стилі для стандартних WPF контролів, але має обмеження: немає нових контролів з Windows 11 (NavigationView, InfoBar, CardControl), немає справжніх Mica/Acrylic ефектів, обмежена кастомізація. Саме тут на сцену виходить WPF UI (пакет Wpf.Ui) — потужна open-source бібліотека, яка надає повноцінну екосистему Fluent Design для WPF додатків.
WPF UI — це не просто набір стилів, а комплексне рішення для створення сучасних Windows 11 додатків у WPF. Бібліотека включає десятки нових контролів (NavigationView для sidebar navigation, CardControl для card-based layouts, InfoBar для notifications), справжні Mica та Acrylic ефекти через Windows API, вбудовану систему тем з підтримкою світлої/темної/системної теми, та навіть MVVM-friendly сервіси для навігації та діалогів. Це найближче, що ви можете отримати до WinUI 3 досвіду, залишаючись у WPF.
У цій статті ми детально розглянемо, як інтегрувати WPF UI у ваш додаток, як використовувати нові контроли, як налаштувати Mica/Acrylic ефекти, як працює система навігації, як створювати власні стилі на базі WPF UI, та як мігрувати існуючий WPF додаток на WPF UI. Ми також порівняємо WPF UI з офіційною Fluent темою та іншими альтернативами (ModernWpf, MahApps.Metro), щоб ви могли зробити інформований вибір для вашого проєкту.
Перш ніж заглибитися у технічні деталі, важливо зрозуміти переваги WPF UI порівняно з офіційною PresentationFramework.Fluent.
| Функціональність | PresentationFramework.Fluent | WPF UI (Wpf.Ui) |
|---|---|---|
| Базові стилі | ✅ Rounded corners, сучасні кольори | ✅ Повна Fluent Design System |
| Нові контроли | ❌ Тільки стандартні WPF контроли | ✅ 30+ нових контролів (NavigationView, InfoBar, CardControl) |
| Mica/Acrylic | ❌ Немає | ✅ Справжні ефекти через Windows API |
| Темна тема | ✅ Базова підтримка | ✅ Повна підтримка з автоматичним перемиканням |
| Навігація | ❌ Потрібно реалізовувати вручну | ✅ Вбудований NavigationService |
| Іконки | ❌ Потрібні сторонні рішення | ✅ Вбудовані Segoe Fluent Icons |
| MVVM підтримка | ❌ Немає спеціальних сервісів | ✅ NavigationService, DialogService, SnackbarService |
| Документація | ⚠️ Мінімальна | ✅ Детальна з прикладами |
| Активна розробка | ⚠️ Базова підтримка | ✅ Активний розвиток, часті оновлення |
| Розмір | 0 KB (вбудовано у .NET) | ~2 MB (NuGet пакет) |
| Складність | Проста (один рядок) | Середня (налаштування + навчання) |
PresentationFramework.Fluent — якщо:
WPF UI — якщо:
Рекомендація: Для нових проєктів з вимогами до сучасного UI — WPF UI. Для простих додатків або швидкої модернізації — офіційна Fluent тема.
Розпочнемо з установки WPF UI та базової конфігурації.
dotnet add package Wpf.Ui
Або через Package Manager Console:
Install-Package Wpf.Ui
Або через Visual Studio: Tools → NuGet Package Manager → Manage NuGet Packages → Search "Wpf.Ui"
Поточна версія: 3.x (перевірте GitHub для останньої версії)
<Application x:Class="MyWPFApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
StartupUri="Views/MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- WPF UI Theme -->
<ui:ThemesDictionary Theme="Light" />
<!-- WPF UI Controls -->
<ui:ControlsDictionary />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Важливо:
ThemesDictionary — базові кольори та стилі темиControlsDictionary — стилі для всіх контролівWPF UI надає спеціальний FluentWindow замість стандартного Window:
<ui:FluentWindow x:Class="MyWPFApp.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="My WPF UI App"
Height="600"
Width="1000"
ExtendsContentIntoTitleBar="True"
WindowBackdropType="Mica"
WindowCornerPreference="Round">
<Grid>
<!-- Content -->
<TextBlock Text="Hello WPF UI!"
FontSize="24"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</ui:FluentWindow>
Code-behind:
using Wpf.Ui.Controls;
namespace MyWPFApp.Views;
public partial class MainWindow : FluentWindow
{
public MainWindow()
{
InitializeComponent();
}
}
Ключові властивості FluentWindow:
ExtendsContentIntoTitleBar — контент заходить у title bar (як у Windows 11 додатках)WindowBackdropType — тип фону (None, Mica, Acrylic, Tabbed)WindowCornerPreference — форма кутів (Default, DoNotRound, Round, RoundSmall)Запустіть додаток. Ви побачите:
WindowBackdropType="Acrylic"
Одна з найпотужніших можливостей WPF UI — це NavigationView, контрол для створення sidebar navigation як у Windows Settings.
<ui:FluentWindow x:Class="MyWPFApp.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="My App"
Height="600"
Width="1000"
ExtendsContentIntoTitleBar="True"
WindowBackdropType="Mica">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Title Bar -->
<ui:TitleBar Grid.Row="0"
Title="My Application"
Icon="pack://application:,,,/Assets/icon.png" />
<!-- Navigation -->
<ui:NavigationView Grid.Row="1"
x:Name="NavigationView"
IsBackButtonVisible="Collapsed"
IsPaneToggleVisible="True"
OpenPaneLength="250">
<!-- Menu Items -->
<ui:NavigationView.MenuItems>
<ui:NavigationViewItem Content="Home"
Icon="{ui:SymbolIcon Home24}"
TargetPageType="{x:Type local:HomePage}" />
<ui:NavigationViewItem Content="Dashboard"
Icon="{ui:SymbolIcon DataUsage24}"
TargetPageType="{x:Type local:DashboardPage}" />
<ui:NavigationViewItem Content="Settings"
Icon="{ui:SymbolIcon Settings24}"
TargetPageType="{x:Type local:SettingsPage}" />
<ui:NavigationViewItemSeparator />
<ui:NavigationViewItem Content="About"
Icon="{ui:SymbolIcon Info24}"
TargetPageType="{x:Type local:AboutPage}" />
</ui:NavigationView.MenuItems>
<!-- Footer Items -->
<ui:NavigationView.FooterMenuItems>
<ui:NavigationViewItem Content="Profile"
Icon="{ui:SymbolIcon Person24}"
TargetPageType="{x:Type local:ProfilePage}" />
</ui:NavigationView.FooterMenuItems>
<!-- Content Frame -->
<Frame x:Name="ContentFrame" />
</ui:NavigationView>
</Grid>
</ui:FluentWindow>
Code-behind з NavigationService:
using Wpf.Ui.Controls;
namespace MyWPFApp.Views;
public partial class MainWindow : FluentWindow
{
public MainWindow()
{
InitializeComponent();
// Налаштування навігації
NavigationView.SetNavigationViewService(
new Wpf.Ui.Services.NavigationService(ContentFrame));
// Навігація на початкову сторінку
NavigationView.Navigate(typeof(HomePage));
}
}
HomePage.xaml:
<Page x:Class="MyWPFApp.Views.HomePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="Home">
<Grid Margin="20">
<StackPanel>
<TextBlock Text="Welcome to My App"
Style="{StaticResource TitleTextBlockStyle}"
Margin="0,0,0,20" />
<ui:CardControl>
<StackPanel>
<TextBlock Text="Getting Started"
FontSize="18"
FontWeight="SemiBold"
Margin="0,0,0,10" />
<TextBlock Text="This is a modern WPF application built with WPF UI library."
TextWrapping="Wrap"
Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
</StackPanel>
</ui:CardControl>
</StackPanel>
</Grid>
</Page>
HomePage.xaml.cs:
using System.Windows.Controls;
namespace MyWPFApp.Views;
public partial class HomePage : Page
{
public HomePage()
{
InitializeComponent();
}
}
Тепер при кліку на menu items у NavigationView автоматично відбувається навігація між сторінками.
Для програмної навігації (наприклад, з кнопки або ViewModel):
// У MainWindow або через DI
private readonly INavigationService _navigationService;
public void NavigateToSettings()
{
_navigationService.Navigate(typeof(SettingsPage));
}
// Навігація назад
public void GoBack()
{
if (_navigationService.CanGoBack)
{
_navigationService.GoBack();
}
}
WPF UI надає десятки нових контролів. Розглянемо найкорисніші.
<ui:CardControl Margin="10">
<StackPanel>
<TextBlock Text="Card Title"
FontSize="18"
FontWeight="SemiBold"
Margin="0,0,0,10" />
<TextBlock Text="Card content goes here. Cards are great for grouping related information."
TextWrapping="Wrap" />
<ui:Button Content="Action"
Appearance="Primary"
HorizontalAlignment="Right"
Margin="0,10,0,0" />
</StackPanel>
</ui:CardControl>
Властивості:
<ui:InfoBar Title="Success"
Message="Your changes have been saved successfully."
Severity="Success"
IsOpen="True"
IsClosable="True"
Margin="10" />
<ui:InfoBar Title="Warning"
Message="This action cannot be undone."
Severity="Warning"
IsOpen="True"
Margin="10" />
<ui:InfoBar Title="Error"
Message="An error occurred while processing your request."
Severity="Error"
IsOpen="True"
Margin="10" />
<ui:InfoBar Title="Information"
Message="New features are available in this version."
Severity="Informational"
IsOpen="True"
Margin="10" />
Severity types:
Informational — синій (за замовчуванням)Success — зеленийWarning — жовтий/помаранчевийError — червонийWPF UI розширює стандартну кнопку:
<StackPanel Orientation="Horizontal" Spacing="10">
<!-- Primary Button -->
<ui:Button Content="Primary"
Appearance="Primary" />
<!-- Secondary Button -->
<ui:Button Content="Secondary"
Appearance="Secondary" />
<!-- Transparent Button -->
<ui:Button Content="Transparent"
Appearance="Transparent" />
<!-- Danger Button -->
<ui:Button Content="Danger"
Appearance="Danger" />
<!-- Icon Button -->
<ui:Button Icon="{ui:SymbolIcon Add24}"
Appearance="Primary" />
<!-- Button with Icon and Text -->
<ui:Button Content="Add Item"
Icon="{ui:SymbolIcon Add24}"
Appearance="Primary" />
</StackPanel>
WPF UI включає Segoe Fluent Icons:
<StackPanel Orientation="Horizontal" Spacing="10">
<ui:SymbolIcon Symbol="Home24" FontSize="24" />
<ui:SymbolIcon Symbol="Settings24" FontSize="24" />
<ui:SymbolIcon Symbol="Person24" FontSize="24" />
<ui:SymbolIcon Symbol="Mail24" FontSize="24" />
<ui:SymbolIcon Symbol="Calendar24" FontSize="24" />
</StackPanel>
Доступні сотні іконок. Повний список: Fluent UI System Icons
<ui:TextBox PlaceholderText="Enter your name"
Icon="{ui:SymbolIcon Person24}"
ClearButtonEnabled="True"
Width="300" />
<ui:PasswordBox PlaceholderText="Enter password"
Icon="{ui:SymbolIcon LockClosed24}"
Width="300"
Margin="0,10,0,0" />
<ui:NumberBox Value="50"
Minimum="0"
Maximum="100"
SpinButtonPlacementMode="Inline"
Width="200" />
<ui:Rating Value="3.5"
Maximum="5"
IsReadOnly="False" />
<ui:ProgressRing IsIndeterminate="True"
Width="50"
Height="50" />
WPF UI має вбудовану систему управління темами з підтримкою світлої, темної та системної теми.
App.xaml.cs:
using Microsoft.Extensions.DependencyInjection;
using System.Windows;
using Wpf.Ui;
namespace MyWPFApp;
public partial class App : Application
{
private IServiceProvider _serviceProvider;
public App()
{
// Налаштування DI
var services = new ServiceCollection();
ConfigureServices(services);
_serviceProvider = services.BuildServiceProvider();
}
private void ConfigureServices(IServiceCollection services)
{
// WPF UI Services
services.AddSingleton<IThemeService, ThemeService>();
services.AddSingleton<ISnackbarService, SnackbarService>();
services.AddSingleton<IDialogService, DialogService>();
services.AddSingleton<INavigationService, NavigationService>();
// Views
services.AddSingleton<MainWindow>();
services.AddTransient<HomePage>();
services.AddTransient<SettingsPage>();
// ViewModels
services.AddTransient<MainViewModel>();
services.AddTransient<SettingsViewModel>();
}
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var mainWindow = _serviceProvider.GetRequiredService<MainWindow>();
mainWindow.Show();
}
}
using Wpf.Ui;
using Wpf.Ui.Appearance;
public class SettingsViewModel : ViewModelBase
{
private readonly IThemeService _themeService;
public SettingsViewModel(IThemeService themeService)
{
_themeService = themeService;
// Отримати поточну тему
CurrentTheme = _themeService.GetTheme();
ChangeThemeCommand = new RelayCommand<string>(ChangeTheme);
}
public ApplicationTheme CurrentTheme { get; private set; }
public ICommand ChangeThemeCommand { get; }
private void ChangeTheme(string themeName)
{
var theme = themeName switch
{
"Light" => ApplicationTheme.Light,
"Dark" => ApplicationTheme.Dark,
_ => ApplicationTheme.Unknown // System default
};
_themeService.SetTheme(theme);
CurrentTheme = theme;
}
}
<ui:CardControl Header="Appearance">
<StackPanel>
<TextBlock Text="Choose your theme"
Margin="0,0,0,10"
Foreground="{DynamicResource TextFillColorSecondaryBrush}" />
<StackPanel Orientation="Horizontal" Spacing="10">
<ui:Button Content="Light"
Icon="{ui:SymbolIcon WeatherSunny24}"
Command="{Binding ChangeThemeCommand}"
CommandParameter="Light" />
<ui:Button Content="Dark"
Icon="{ui:SymbolIcon WeatherMoon24}"
Command="{Binding ChangeThemeCommand}"
CommandParameter="Dark" />
<ui:Button Content="System"
Icon="{ui:SymbolIcon Desktop24}"
Command="{Binding ChangeThemeCommand}"
CommandParameter="System" />
</StackPanel>
</StackPanel>
</ui:CardControl>
public class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var themeService = _serviceProvider.GetRequiredService<IThemeService>();
// Встановити системну тему
themeService.SetTheme(ApplicationTheme.Unknown); // Unknown = System default
// Слідкувати за змінами системної теми
SystemThemeWatcher.Watch(
this,
WindowBackdropType.Mica,
updateAccents: true);
}
}
WPF UI надає справжні Mica та Acrylic ефекти через Windows API.
<ui:FluentWindow WindowBackdropType="Mica">
<!-- Content -->
</ui:FluentWindow>
Типи Mica:
Mica — стандартний Mica (адаптується до wallpaper)MicaAlt — альтернативний Mica (більш subtle)Tabbed — для tabbed interfaces<ui:FluentWindow WindowBackdropType="Acrylic">
<!-- Content -->
</ui:FluentWindow>
Acrylic створює більш виражений blur ефект ніж Mica.
using Wpf.Ui.Appearance;
public partial class MainWindow : FluentWindow
{
public MainWindow()
{
InitializeComponent();
// Встановити Mica
WindowBackdrop.ApplyBackdrop(this, WindowBackdropType.Mica);
// Або Acrylic
// WindowBackdrop.ApplyBackdrop(this, WindowBackdropType.Acrylic);
}
}
Можна застосувати acrylic до окремих контролів:
<Border Background="{DynamicResource ApplicationBackgroundBrush}"
CornerRadius="8"
Padding="20">
<Border.Effect>
<ui:AcrylicEffect TintColor="#80FFFFFF"
TintOpacity="0.8"
NoiseOpacity="0.03" />
</Border.Effect>
<StackPanel>
<TextBlock Text="Acrylic Panel"
FontSize="18"
FontWeight="SemiBold" />
<TextBlock Text="This panel has acrylic effect"
Margin="0,10,0,0" />
</StackPanel>
</Border>
WPF UI надає сервіси для показу notifications та діалогів.
Налаштування у MainWindow:
<ui:FluentWindow>
<Grid>
<!-- Content -->
<!-- Snackbar Presenter (зазвичай внизу) -->
<ui:SnackbarPresenter x:Name="SnackbarPresenter"
VerticalAlignment="Bottom"
HorizontalAlignment="Center"
Margin="0,0,0,20" />
</Grid>
</ui:FluentWindow>
Code-behind:
public partial class MainWindow : FluentWindow
{
private readonly ISnackbarService _snackbarService;
public MainWindow(ISnackbarService snackbarService)
{
InitializeComponent();
_snackbarService = snackbarService;
_snackbarService.SetSnackbarPresenter(SnackbarPresenter);
}
}
Використання у ViewModel:
public class HomeViewModel : ViewModelBase
{
private readonly ISnackbarService _snackbarService;
public HomeViewModel(ISnackbarService snackbarService)
{
_snackbarService = snackbarService;
SaveCommand = new RelayCommand(Save);
}
public ICommand SaveCommand { get; }
private async void Save()
{
// Симуляція збереження
await Task.Delay(1000);
// Показати success notification
_snackbarService.Show(
"Success",
"Your changes have been saved.",
ControlAppearance.Success,
new SymbolIcon(SymbolRegular.Checkmark24),
TimeSpan.FromSeconds(3));
}
}
Типи Snackbar:
// Success
_snackbarService.Show("Success", "Operation completed", ControlAppearance.Success);
// Warning
_snackbarService.Show("Warning", "Please review your input", ControlAppearance.Caution);
// Error
_snackbarService.Show("Error", "Something went wrong", ControlAppearance.Danger);
// Info
_snackbarService.Show("Info", "New features available", ControlAppearance.Info);
Налаштування:
public partial class MainWindow : FluentWindow
{
private readonly IDialogService _dialogService;
public MainWindow(IDialogService dialogService)
{
InitializeComponent();
_dialogService = dialogService;
_dialogService.SetDialogHost(this); // MainWindow як host для діалогів
}
}
Простий діалог:
public async Task ShowSimpleDialog()
{
var result = await _dialogService.ShowSimpleDialogAsync(
new SimpleContentDialogCreateOptions
{
Title = "Confirm Delete",
Content = "Are you sure you want to delete this item? This action cannot be undone.",
PrimaryButtonText = "Delete",
SecondaryButtonText = "Cancel",
CloseButtonText = null
});
if (result == ContentDialogResult.Primary)
{
// Користувач натиснув Delete
DeleteItem();
}
}
Custom діалог з ViewModel:
<!-- Views/Dialogs/EditUserDialog.xaml -->
<ui:ContentDialog x:Class="MyWPFApp.Views.Dialogs.EditUserDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Title="Edit User"
PrimaryButtonText="Save"
SecondaryButtonText="Cancel">
<StackPanel Width="400">
<ui:TextBox PlaceholderText="Name"
Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"
Margin="0,0,0,10" />
<ui:TextBox PlaceholderText="Email"
Text="{Binding Email, UpdateSourceTrigger=PropertyChanged}"
Margin="0,0,0,10" />
<ui:NumberBox PlaceholderText="Age"
Value="{Binding Age}"
Minimum="0"
Maximum="150" />
</StackPanel>
</ui:ContentDialog>
// Показати custom діалог
var dialog = new EditUserDialog
{
DataContext = new EditUserViewModel(currentUser)
};
var result = await _dialogService.ShowAsync(dialog);
if (result == ContentDialogResult.Primary)
{
// Користувач натиснув Save
var viewModel = (EditUserViewModel)dialog.DataContext;
SaveUser(viewModel.Name, viewModel.Email, viewModel.Age);
}
WPF UI дозволяє кастомізувати кольори та стилі.
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ui:ThemesDictionary Theme="Light" />
<ui:ControlsDictionary />
</ResourceDictionary.MergedDictionaries>
<!-- Custom Accent Color -->
<Color x:Key="SystemAccentColor">#6B46C1</Color>
<Color x:Key="SystemAccentColorSecondary">#553C9A</Color>
<Color x:Key="SystemAccentColorTertiary">#44307A</Color>
<SolidColorBrush x:Key="SystemAccentBrush" Color="{StaticResource SystemAccentColor}" />
<SolidColorBrush x:Key="SystemAccentBrushSecondary" Color="{StaticResource SystemAccentColorSecondary}" />
<SolidColorBrush x:Key="SystemAccentBrushTertiary" Color="{StaticResource SystemAccentColorTertiary}" />
</ResourceDictionary>
</Application.Resources>
<!-- Custom Primary Button -->
<Style x:Key="LargePrimaryButtonStyle"
TargetType="ui:Button"
BasedOn="{StaticResource {x:Type ui:Button}}">
<Setter Property="Appearance" Value="Primary" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Padding" Value="24,12" />
<Setter Property="MinWidth" Value="150" />
</Style>
<!-- Custom Card -->
<Style x:Key="HighlightCardStyle"
TargetType="ui:CardControl"
BasedOn="{StaticResource {x:Type ui:CardControl}}">
<Setter Property="BorderBrush" Value="{DynamicResource SystemAccentBrush}" />
<Setter Property="BorderThickness" Value="2" />
</Style>
Для великих проєктів:
Styles/
├── Colors.xaml
├── Typography.xaml
├── Buttons.xaml
├── Cards.xaml
└── Theme.xaml
Theme.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml">
<ResourceDictionary.MergedDictionaries>
<!-- WPF UI Base -->
<ui:ThemesDictionary Theme="Light" />
<ui:ControlsDictionary />
<!-- Custom Styles -->
<ResourceDictionary Source="Colors.xaml" />
<ResourceDictionary Source="Typography.xaml" />
<ResourceDictionary Source="Buttons.xaml" />
<ResourceDictionary Source="Cards.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Якщо ви вже використовуєте PresentationFramework.Fluent, міграція на WPF UI проста.
Було:
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/PresentationFramework.Fluent;component/Themes/Fluent.xaml" />
</ResourceDictionary.MergedDictionaries>
Стало:
<ResourceDictionary.MergedDictionaries>
<ui:ThemesDictionary Theme="Light" />
<ui:ControlsDictionary />
</ResourceDictionary.MergedDictionaries>
Було:
<Window x:Class="MyApp.MainWindow">
Стало:
<ui:FluentWindow x:Class="MyApp.MainWindow"
WindowBackdropType="Mica">
Було:
<Style x:Key="PrimaryButtonStyle" TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Background" Value="{DynamicResource SystemAccentBrush}" />
</Style>
Стало:
<ui:Button Appearance="Primary" />
<!-- Або -->
<Style x:Key="PrimaryButtonStyle" TargetType="ui:Button" BasedOn="{StaticResource {x:Type ui:Button}}">
<Setter Property="Appearance" Value="Primary" />
</Style>
Тепер можна використовувати:
Завдання: Створіть WPF додаток з WPF UI, NavigationView та 3 сторінками.
Вимоги:
Критерії успіху:
Завдання: Додайте підтримку тем, SnackbarService та DialogService.
Вимоги:
Критерії успіху:
Завдання: Створіть повноцінний CRUD додаток з WPF UI.
Вимоги:
Критерії успіху:
WPF UI — не єдина бібліотека для модернізації WPF. Розглянемо альтернативи.
ModernWpf — інша популярна бібліотека для Fluent Design у WPF.
| Характеристика | WPF UI | ModernWpf |
|---|---|---|
| Активність | ✅ Активний розвиток | ⚠️ Менш активний |
| Windows 11 features | ✅ Mica, rounded corners | ⚠️ Базова підтримка |
| Нові контроли | ✅ NavigationView, InfoBar, CardControl | ✅ NavigationView, InfoBar |
| Документація | ✅ Детальна | ⚠️ Базова |
| Розмір | ~2 MB | ~1.5 MB |
| Стиль | Windows 11 Fluent | Windows 10 Fluent |
| Сумісність | .NET 6+ | .NET Framework 4.6.2+ |
Висновок: WPF UI більш сучасний та активно розвивається. ModernWpf підходить якщо потрібна підтримка .NET Framework.
MahApps.Metro — старша бібліотека з Metro/Modern UI стилями.
| Характеристика | WPF UI | MahApps.Metro |
|---|---|---|
| Стиль | Fluent Design (Windows 11) | Metro Design (Windows 8) |
| Сучасність | ✅ Дуже сучасний | ⚠️ Застарілий вигляд |
| Контроли | ✅ Багато нових | ✅ Багато, але старі |
| Hamburger Menu | ✅ NavigationView | ✅ HamburgerMenu |
| Складність | Середня | Висока |
| Документація | ✅ Детальна | ✅ Детальна |
Висновок: MahApps.Metro застарів візуально. Для нових проєктів WPF UI краще.
HandyControl — китайська бібліотека з великою колекцією контролів.
| Характеристика | WPF UI | HandyControl |
|---|---|---|
| Стиль | Fluent Design | Custom (схожий на Material) |
| Кількість контролів | ~30 | ~80+ |
| Документація | Англійська | Переважно китайська |
| Windows 11 integration | ✅ Mica, Acrylic | ❌ Немає |
| Складність | Середня | Висока |
Висновок: HandyControl має більше контролів, але WPF UI краще інтегрується з Windows 11.
Використовуйте WPF UI якщо:
Використовуйте ModernWpf якщо:
Використовуйте MahApps.Metro якщо:
Використовуйте HandyControl якщо:
Підсумуємо найкращі практики роботи з WPF UI.
WPF UI сервіси (ThemeService, NavigationService, DialogService) розроблені для DI:
// Налаштування DI
services.AddSingleton<IThemeService, ThemeService>();
services.AddSingleton<INavigationService, NavigationService>();
services.AddSingleton<IDialogService, DialogService>();
services.AddSingleton<ISnackbarService, SnackbarService>();
Це дозволяє легко тестувати та підтримувати код.
MyWPFApp/
├── Views/
│ ├── Pages/
│ │ ├── HomePage.xaml
│ │ ├── DashboardPage.xaml
│ │ └── SettingsPage.xaml
│ ├── Dialogs/
│ │ └── EditUserDialog.xaml
│ └── MainWindow.xaml
├── ViewModels/
│ ├── HomeViewModel.cs
│ ├── DashboardViewModel.cs
│ └── SettingsViewModel.cs
├── Models/
├── Services/
├── Styles/
│ ├── Colors.xaml
│ ├── Typography.xaml
│ └── Theme.xaml
└── App.xaml
Замість Border використовуйте CardControl:
<!-- Погано -->
<Border Background="White" CornerRadius="8" Padding="16">
<StackPanel>
<!-- Content -->
</StackPanel>
</Border>
<!-- Добре -->
<ui:CardControl>
<StackPanel>
<!-- Content -->
</StackPanel>
</ui:CardControl>
CardControl автоматично адаптується до теми та має правильний elevation.
Замість власних стилів використовуйте вбудовані Appearance:
<!-- Погано -->
<Button Background="Blue" Foreground="White" />
<!-- Добре -->
<ui:Button Appearance="Primary" />
Замість PNG/SVG іконок використовуйте SymbolIcon:
<!-- Погано -->
<Image Source="/Assets/home.png" Width="24" Height="24" />
<!-- Добре -->
<ui:SymbolIcon Symbol="Home24" FontSize="24" />
SymbolIcon автоматично адаптується до теми та має кращу якість.
Завжди тестуйте додаток у світлій та темній темі:
// У тестах або debug mode
#if DEBUG
_themeService.SetTheme(ApplicationTheme.Dark);
#endif
<!-- Погано -->
<TextBlock Foreground="Black" />
<!-- Добре -->
<TextBlock Foreground="{DynamicResource TextFillColorPrimaryBrush}" />
Mica працює тільки на Windows 11. Додайте fallback:
public MainWindow()
{
InitializeComponent();
// Перевірка Windows 11
if (Environment.OSVersion.Version.Build >= 22000)
{
WindowBackdrop.ApplyBackdrop(this, WindowBackdropType.Mica);
}
else
{
// Fallback для Windows 10
Background = new SolidColorBrush(Colors.White);
}
}
WPF UI має деякі обмеження, про які важливо знати.
WPF UI вимагає .NET 6 або новіше. Не працює на .NET Framework.
Рішення: Мігруйте на .NET 6/7/8 або використовуйте ModernWpf.
Mica ефект працює тільки на Windows 11 build 22000+.
Рішення: Додайте fallback для Windows 10 (solid color або gradient).
Acrylic може впливати на продуктивність на слабких GPU.
Рішення: Використовуйте Mica замість Acrylic для main window. Acrylic тільки для dialogs.
WPF UI може конфліктувати з MahApps.Metro, ModernWpf, HandyControl.
Рішення: Не змішуйте UI бібліотеки. Виберіть одну.
WPF UI додає ~2 MB до розміру додатку.
Рішення: Для мінімальних додатків використовуйте офіційну Fluent тему. Для повноцінних — 2 MB не критично.
WPF UI — це найпотужніша бібліотека для створення сучасних Windows 11 додатків у WPF. Основні переваги:
Повна екосистема Fluent Design: Не просто стилі, а комплексне рішення з новими контролами (NavigationView, InfoBar, CardControl), справжніми Mica/Acrylic ефектами, вбудованою системою тем, та MVVM-friendly сервісами.
Справжні Windows 11 ефекти: Mica та Acrylic працюють через Windows API, створюючи справжній native вигляд. Це неможливо з офіційною Fluent темою.
Активний розвиток: Бібліотека активно розвивається, регулярні оновлення, детальна документація, велика спільнота. Це важливо для довгострокових проєктів.
MVVM-friendly: ThemeService, NavigationService, DialogService, SnackbarService — все розроблено для DI та MVVM pattern. Легко інтегрується з сучасними архітектурами.
Обмеження: Вимагає .NET 6+, Mica тільки на Windows 11, додає ~2 MB до розміру. Для більшості проєктів це не критично.
WPF UI робить WPF додатки сучасними, професійними та приємними у використанні. Це інвестиція у user experience, яка окупається довірою користувачів та конкурентною перевагою на ринку.
Попередня стаття: Fluent UI у WPF — офіційна Fluent тема від Microsoft.
Наступна стаття: XAML Namespaces та Resources — робота з просторами імен та ресурсами у XAML.
Fluent UI у WPF — сучасний дизайн Windows 11
Інтеграція Fluent Design System у WPF додатки: PresentationFramework.Fluent, стилізація контролів, кастомізація тем, створення власних стилів з BasedOn
HandyControl — велика бібліотека UI контролів для WPF
Інтеграція HandyControl у WPF: 80+ сучасних контролів, Material Design стилі, темна тема, анімації, та повна екосистема для створення красивих додатків