From wpf-dev-pack
Guides integration of Wpf.Ui library for Fluent Design in WPF apps, including FluentWindow, NavigationView, SnackbarService, theme setup, and GenericHost DI. Use for modern WPF UIs.
How this skill is triggered — by the user, by Claude, or both
Slash command
/wpf-dev-pack:integrating-wpfui-fluentsonnetThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Wpf.Ui 4.x 기반 Fluent Design WPF 앱 구현 가이드.
Wpf.Ui 4.x 기반 Fluent Design WPF 앱 구현 가이드.
<PackageReference Include="WPF-UI" Version="4.2.*" />
<Application x:Class="MyApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Wpf.Ui;component/Styles/Controls.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
<ui:FluentWindow x:Class="MyApp.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="MyApp" Height="600" Width="800"
ExtendsContentIntoTitleBar="True"
WindowBackdropType="Mica">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ui:TitleBar Grid.Row="0" Title="MyApp" />
<ui:NavigationView Grid.Row="1"
x:Name="RootNavigation"
PaneDisplayMode="Left"
IsBackButtonVisible="Collapsed">
<ui:NavigationView.MenuItems>
<ui:NavigationViewItem Content="Home"
TargetPageType="{x:Type local:HomePage}"
Icon="{ui:SymbolIcon Home24}" />
<ui:NavigationViewItem Content="Settings"
TargetPageType="{x:Type local:SettingsPage}"
Icon="{ui:SymbolIcon Settings24}" />
</ui:NavigationView.MenuItems>
</ui:NavigationView>
</Grid>
</ui:FluentWindow>
namespace MyApp;
public partial class MainWindow : FluentWindow
{
public MainWindow(
MainWindowViewModel viewModel,
INavigationService navigationService,
ISnackbarService snackbarService,
IContentDialogService contentDialogService)
{
DataContext = viewModel;
InitializeComponent();
navigationService.SetNavigationControl(RootNavigation);
snackbarService.SetSnackbarPresenter(RootSnackbar);
contentDialogService.SetDialogHost(RootContentDialog);
}
}
namespace MyApp;
public partial class App : Application
{
private static readonly IHost _host = Host.CreateDefaultBuilder()
.ConfigureServices((_, services) =>
{
// Wpf.Ui Services
services.AddSingleton<INavigationService, NavigationService>();
services.AddSingleton<ISnackbarService, SnackbarService>();
services.AddSingleton<IContentDialogService, ContentDialogService>();
services.AddSingleton<IThemeService, ThemeService>();
// Windows
services.AddSingleton<MainWindow>();
services.AddSingleton<MainWindowViewModel>();
// Pages (Transient for navigation)
services.AddTransient<HomePage>();
services.AddTransient<HomeViewModel>();
services.AddTransient<SettingsPage>();
services.AddTransient<SettingsViewModel>();
})
.Build();
protected override async void OnStartup(StartupEventArgs e)
{
await _host.StartAsync();
var mainWindow = _host.Services.GetRequiredService<MainWindow>();
mainWindow.Show();
base.OnStartup(e);
}
protected override async void OnExit(ExitEventArgs e)
{
await _host.StopAsync();
_host.Dispose();
base.OnExit(e);
}
}
// Page는 ui:INavigableView<TViewModel>을 구현
// Page implements ui:INavigableView<TViewModel>
public partial class HomePage : Page, INavigableView<HomeViewModel>
{
public HomeViewModel ViewModel { get; }
public HomePage(HomeViewModel viewModel)
{
ViewModel = viewModel;
DataContext = viewModel;
InitializeComponent();
}
}
// ViewModel에서 INavigationService 주입
// Inject INavigationService in ViewModel
[RelayCommand]
private void NavigateToSettings()
{
_navigationService.Navigate(typeof(SettingsPage));
}
// ViewModel에서 사용
// Use in ViewModel
_snackbarService.Show(
"성공", // Title
"저장되었습니다.", // Message
ControlAppearance.Success,
new SymbolIcon(SymbolRegular.Checkmark24),
TimeSpan.FromSeconds(3));
<ui:SnackbarPresenter x:Name="RootSnackbar" Grid.Row="2" />
// ViewModel에서 사용
// Use in ViewModel
var result = await _contentDialogService.ShowSimpleDialogAsync(
new SimpleContentDialogCreateOptions
{
Title = "삭제 확인",
Content = "정말 삭제하시겠습니까?",
PrimaryButtonText = "삭제",
CloseButtonText = "취소"
});
if (result == ContentDialogResult.Primary)
{
// 삭제 처리
// Handle deletion
}
<ui:ContentDialogService x:Name="RootContentDialog" Grid.Row="1" />
// 테마 전환
// Switch theme
ApplicationThemeManager.Apply(ApplicationTheme.Dark);
ApplicationThemeManager.Apply(ApplicationTheme.Light);
// 시스템 테마 감지 + 자동 적용
// Detect system theme + auto-apply
ApplicationThemeManager.ApplySystemTheme();
WPF-UI는 CommunityToolkit.Mvvm과 자연스럽게 통합됩니다:
public sealed partial class HomeViewModel : ObservableObject
{
private readonly ISnackbarService _snackbarService;
public HomeViewModel(ISnackbarService snackbarService)
{
_snackbarService = snackbarService;
}
[ObservableProperty] private string _searchText = string.Empty;
[RelayCommand]
private void Search()
{
_snackbarService.Show("검색", $"'{SearchText}' 검색 중...",
ControlAppearance.Info, null, TimeSpan.FromSeconds(2));
}
}
FluentWindow 상속 (일반 Window 대신)ExtendsContentIntoTitleBar="True" + ui:TitleBar 조합INavigableView<TViewModel> 구현INavigationService.SetNavigationControl()은 MainWindow 생성자에서 호출npx claudepluginhub christian289/dotnet-with-claudecode --plugin wpf-dev-packBuilding WPF on .NET 8+. Host builder, MVVM Toolkit, Fluent theme, performance, modern C# patterns.
Scaffolds WPF project structures with MVVM, DI, and best practices using CommunityToolkit.Mvvm (default) or Prism. Use for new WPF apps, scratch solutions, or setups via /wpf-dev-pack:make-wpf-project.
Designs WinUI 3 UIs and reviews XAML for correctness, covering layout planning, control selection, Fluent Design, theming (Light/Dark/HighContrast), typography, spacing, brushes, accessibility, and data binding.