更新客户端渲染,更新了壳

This commit is contained in:
QWQLwToo
2026-07-06 23:05:40 +08:00
parent e7dd87bf7e
commit 31d778710b
1311 changed files with 172662 additions and 1582 deletions
@@ -0,0 +1,5 @@
###############
# temp file #
###############
*.yml
.manifest
@@ -0,0 +1,19 @@
# What is WPF
WPF (Windows Presentation Foundation) is a resolution-independent UI framework for building Windows desktop applications. It provides vector-based graphics, advanced layout, data binding, multimedia, animation, and extensive styling and templating capabilities.
## .NET Framework vs Modern .NET
WPF has two implementations:
**Modern .NET** (.NET 6+): Open-source implementation hosted on GitHub. Provides improved performance, new APIs, side-by-side deployment, and modern tooling. Despite .NET being cross-platform, WPF only runs on Windows.
**.NET Framework 4**: Legacy Windows-only implementation. Maintained for compatibility with existing applications but receives minimal new features.
New WPF applications should target modern .NET (.NET 6 or later) to benefit from:
- Better performance and reduced memory usage
- Regular updates and new features
- Modern C# language versions
- Improved debugging and diagnostics
- Side-by-side deployment without machine-wide installations
@@ -0,0 +1,211 @@
# Accent Colors
Accent colors provide visual emphasis and brand identity in WPF UI applications. The library manages accent color resources that automatically adapt to light and dark themes.
> [!TIP]
> Use `SystemThemeWatcher.Watch(this)` in your main window constructor to automatically sync accent colors with Windows personalization settings.
## Apply System Accent
Use the system's personalization accent color:
```csharp
using Wpf.Ui.Appearance;
ApplicationAccentColorManager.ApplySystemAccent();
```
## Apply Theme with Accent
Apply theme and accent together:
```csharp
using Wpf.Ui.Appearance;
using Wpf.Ui.Controls;
ApplicationThemeManager.Apply(
ApplicationTheme.Dark,
WindowBackdropType.Mica,
updateAccent: true // Automatically applies system accent
);
```
Available backdrop types: `None`, `Auto`, `Mica`, `Acrylic`, `Tabbed`.
> [!IMPORTANT]
> Always use `DynamicResource` (not `StaticResource`) for accent color bindings to receive runtime updates when accent changes.
## Apply Custom Accent
Set a custom accent color:
```csharp
ApplicationAccentColorManager.Apply(
Color.FromArgb(0xFF, 0xEE, 0x00, 0xBB),
ApplicationTheme.Dark
);
```
Retrieve the Windows colorization color programmatically:
```csharp
Color colorizationColor = ApplicationAccentColorManager.GetColorizationColor();
ApplicationAccentColorManager.Apply(colorizationColor, ApplicationTheme.Dark);
```
## Accent Color Resources
WPF UI provides these accent color resources:
### System Accent Colors
Base accent colors that update when you call `ApplicationAccentColorManager.Apply()`:
- `SystemAccentColor` - Primary system accent
- `SystemAccentColorPrimary` - Lighter/darker variant for light/dark themes
- `SystemAccentColorSecondary` - More prominent variant (most commonly used)
- `SystemAccentColorTertiary` - Strongest variant
```xml
<Border Background="{DynamicResource SystemAccentColorSecondaryBrush}" />
```
> [!TIP]
> `SystemAccentColorSecondary` is the most commonly used variant for interactive elements and provides optimal contrast in both light and dark themes.
### Accent Text Colors
For text and interactive elements like links:
- `AccentTextFillColorPrimaryBrush` - Primary accent text (rest/hover state)
- `AccentTextFillColorSecondaryBrush` - Secondary accent text
- `AccentTextFillColorTertiaryBrush` - Tertiary accent text (pressed state)
- `AccentTextFillColorDisabledBrush` - Disabled accent text
```xml
<ui:Anchor
Content="WPF UI Documentation"
NavigateUri="https://wpfui.lepo.co/"
Foreground="{DynamicResource AccentTextFillColorPrimaryBrush}" />
```
### Accent Fill Colors
For button backgrounds and filled surfaces:
- `AccentFillColorDefaultBrush` - Default accent fill
- `AccentFillColorSecondaryBrush` - Secondary fill (90% opacity)
- `AccentFillColorTertiaryBrush` - Tertiary fill (80% opacity)
- `AccentFillColorDisabledBrush` - Disabled state fill
```xml
<Button Background="{DynamicResource AccentFillColorDefaultBrush}" />
```
### Text on Accent Colors
For text displayed on accent-colored backgrounds. These resources automatically adjust to black or white based on accent brightness:
- `TextOnAccentFillColorPrimary` - Primary text color on accent backgrounds
- `TextOnAccentFillColorSecondary` - Secondary text on accent backgrounds
- `TextOnAccentFillColorDisabled` - Disabled text on accent backgrounds
> [!NOTE]
> Text colors automatically switch between black and white when accent brightness exceeds 80% HSV to maintain readability.
## Theme-Specific Behavior
Accent variants adjust automatically based on the application theme:
**Dark Theme:**
- Primary: Base color + 17 brightness, -30% saturation
- Secondary: Base color + 17 brightness, -45% saturation
- Tertiary: Base color + 17 brightness, -65% saturation
**Light Theme:**
- Primary: Base color - 10 brightness
- Secondary: Base color - 25 brightness
- Tertiary: Base color - 40 brightness
> [!NOTE]
> Brightness adjustments are calculated in HSV color space. Negative values darken the color, positive values lighten it.
## Advanced: Custom Accent Variants
Specify all accent variants manually:
```csharp
ApplicationAccentColorManager.Apply(
systemAccent: Color.FromArgb(0xFF, 0x00, 0x78, 0xD4),
primaryAccent: Color.FromArgb(0xFF, 0x00, 0x67, 0xC0),
secondaryAccent: Color.FromArgb(0xFF, 0x00, 0x3E, 0x92),
tertiaryAccent: Color.FromArgb(0xFF, 0x00, 0x1A, 0x68)
);
```
> [!CAUTION]
> Manually specified accent variants won't automatically adjust when theme changes. Consider using automatic variant generation unless you need precise color control.
## Accessing Current Accent
Read current accent colors from `ApplicationAccentColorManager`:
```csharp
Color currentSystemAccent = ApplicationAccentColorManager.SystemAccent;
Color currentPrimaryAccent = ApplicationAccentColorManager.PrimaryAccent;
Color currentSecondaryAccent = ApplicationAccentColorManager.SecondaryAccent;
Color currentTertiaryAccent = ApplicationAccentColorManager.TertiaryAccent;
Brush accentBrush = ApplicationAccentColorManager.SystemAccentBrush;
```
## Theme Changed Event
Monitor accent changes when theme is applied:
```csharp
ApplicationThemeManager.Changed += (theme, accent) =>
{
Debug.WriteLine($"Theme changed to {theme}, accent: {accent}");
};
```
## Automatic System Theme Tracking
Use `SystemThemeWatcher` to automatically update theme and accent when Windows settings change:
```csharp
using Wpf.Ui.Appearance;
public partial class MainWindow : Window
{
public MainWindow()
{
// Watch system theme changes with Mica backdrop and accent updates
SystemThemeWatcher.Watch(this);
InitializeComponent();
}
}
```
With custom backdrop and accent settings:
```csharp
SystemThemeWatcher.Watch(
this,
WindowBackdropType.Acrylic,
updateAccents: true
);
```
Stop watching for theme changes:
```csharp
SystemThemeWatcher.UnWatch(this);
```
> [!NOTE]
> `SystemThemeWatcher` monitors `WM_WININICHANGE` messages and automatically applies system theme and accent when Windows personalization settings change.
@@ -0,0 +1,40 @@
# Visual Studio 2022 Extension for WPF UI
Visual Studio allows you to add extensions that can be installed in several ways:
- Build them locally and then install the `.vsix` package.
- Download the extension from the internet and install the `.vsix` file.
- Install the extension using the search in _Visual Studio_.
In this tutorial, we'll cover the last way, if you want to know more, check out [**Manage extensions for Visual Studio**](https://learn.microsoft.com/en-us/visualstudio/ide/finding-and-using-visual-studio-extensions?view=vs-2022).
In any case, if you want to download a plugin and install it manually, or leave your review, you can find it in the Visual Studio Marketplace:
https://marketplace.visualstudio.com/items?itemName=lepo.wpf-ui
> [!NOTE]
> The source code for **WPF UI** _Visual Studio 2022_ extension is public and you can [check it out here](https://github.com/lepoco/wpfui/tree/development/src/Wpf.Ui.Extension/Wpf.Ui.Extension).
## How to?
1. Install Visual Studio 2022 from [Visual Studio 2022 downloads](https://visualstudio.microsoft.com/downloads/).
2. After installation, open Visual Studio
3. Expand the _Extensions_ tab in the menu and then click _Manage Extensions_
![Extensions tab in Visual Studio](https://user-images.githubusercontent.com/13592821/192057892-39ae96f8-ba25-4fb8-a081-0b8d530f79bf.png)
4. In the _Online_ tab, use the search engine to enter _WPF-UI_ in it, then click _Download_
![Online tab in Extension Manager for Visual Studio](https://user-images.githubusercontent.com/13592821/192058027-44929773-548d-4ae1-a6e4-e922c04e82e8.png)
5. After downloading, restart _Visual Studio_
6. After restarting, you will see a window asking you to confirm the installation.
![Confirm Visual Studio Installation](https://user-images.githubusercontent.com/13592821/192058231-c5587473-a44d-4046-a6ad-8cd0a3cdc9df.png)
7. Once installed, you can restart _Visual Studio_ and click _Create new project_
![Create new project](https://user-images.githubusercontent.com/13592821/192058452-f1f9005c-4d40-482a-96fb-5dccbafb4102.png)
8. In the top right corner, you can select the project type
![Project type filter](https://user-images.githubusercontent.com/13592821/192058531-186b0eba-14c0-4761-9781-dd8880e2763a.png)
9. Voila, you have just installed the **WPF UI** extension.
## Done!
After creating a project, you can familiarize yourself with its structure and proceed to further steps.
- [WPF UI - Getting started](/documentation/getting-started)
- [Introduction to the MVVM Toolkit](https://learn.microsoft.com/en-us/windows/communitytoolkit/mvvm/introduction)
- [.NET Generic Host in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-6.0)
@@ -0,0 +1,41 @@
# FontIcon
`FontIcon` is a control responsible for rendering icons based on the provided font.
### Implementation
```csharp
class Wpf.Ui.Controls.FontIcon
```
## Exposes
```csharp
// Gets or sets displayed glyph
FontIcon.Glyph = '\uE00B';
```
```csharp
// Gets or sets used font family
FontIcon.FontFamily = "Segoe Fluent Icons";
```
```csharp
// Icon foreground
FontIcon.Foreground = Brushes.White;
```
```csharp
// Icon size
FontIcon.FontSize = 16;
```
### How to use
```xml
<ui:FontIcon
Glyph="&#xe00b;"
FontFamily="{DynamicResource SegoeFluentIcons}"
FontSize="16"
Foreground="White"/>
```
@@ -0,0 +1 @@
# WPF UI - Editor
@@ -0,0 +1 @@
# WPF UI - Monaco Editor
@@ -0,0 +1,8 @@
# WPF UI Gallery
**WPF UI Gallery** is a free application available in the _Microsoft Store_, with which you can test all functionalities.
https://apps.microsoft.com/store/detail/wpf-ui/9N9LKV8R9VGM
```powershell
$ winget install 'WPF UI'
```
@@ -0,0 +1,77 @@
# Getting started
## Adding dictionaries
[XAML](https://docs.microsoft.com/en-us/dotnet/desktop/wpf/xaml/?view=netdesktop-6.0), and hence WPF, operate on resource dictionaries. These are HTML-like files that describe the appearance and various aspects of the [controls](https://wpfui.lepo.co/documentation/controls). **WPF UI** adds its own sets of these files to tell the application how the controls should look.
There should be a file called `App.xaml` in your new application. Add new dictionaries to it using **WPF UI** `ControlsDictionary` and `ThemesDictionary` classes:
```xml
<Application
...
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ui:ThemesDictionary Theme="Dark" />
<ui:ControlsDictionary />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
```
Notice that the `ThemeDictionary` lets you choose a color theme, `Light` or `Dark`.
## The main window
There should be a `MainWindow.xaml` file in your newly created application. It contains the arrangement of the controls used and their parameters.
```xml
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>
```
Add the **WPF UI** library namespace to this window to tell the XAML compiler that you will be using controls from the library.
```xml
<Window
...
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" />
```
## Adding controls
To add a new control from the **WPF UI** library, just enter its class name, prefixing it with the `ui:` prefix:
```xml
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ui:SymbolIcon Symbol="Fluent24"/>
</Grid>
</Window>
```
# Well...
That's it when it comes to the basics, information about individual controls can be found in [documentation](https://wpfui.lepo.co/documentation/). Rules for building a WPF application can be found in the [official Microsoft documentation](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/styles-templates-overview?view=netdesktop-6.0). You can check out [**how to build MVVM applications** here](https://learn.microsoft.com/en-us/windows/communitytoolkit/mvvm/puttingthingstogether).
If you think this documentation needs improvement, please [help improve it here](https://github.com/lepoco/wpfui/tree/development/docs/tutorial).
@@ -0,0 +1,52 @@
# Fluent System Icons
Fluent System Icons is a set of icons that is designed to be used with Microsoft's Fluent Design System. It is a collection of over 1,500 icons that are designed to be modern, consistent, and scalable, and can be used in a variety of applications and platforms, including web and mobile applications.
The Fluent System Icons set includes a range of icons, such as those for basic navigation, media playback, communication, and more. The icons are available in various sizes, from 16x16 to 512x512 pixels, and are provided in vector format, allowing for easy scaling and customization.
Fluent System Icons is available for free and can be downloaded from the official Microsoft website. It is also open source, meaning that developers can contribute to the icon set or create their own custom icons based on the existing ones.
[Fluent UI System Icons](https://github.com/microsoft/fluentui-system-icons)
**WPF UI** uses Fluent UI System Icons in most of the graphical controls.
## Getting started
Icons are displayed by using the font that comes with the library. All glyphs are mapped to the [SymbolRegular](https://github.com/lepoco/wpfui/blob/main/src/Wpf.Ui/Common/SymbolRegular.cs) and [SymbolFilled](https://github.com/lepoco/wpfui/blob/main/src/Wpf.Ui/Common/SymbolFilled.cs) enums.
Icon controls and fonts will be automatically added to your application if you add `ControlsDictionary` in the **App.xaml** file:
```xml
<Application
...
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml">
<Application.Resources>
<ui:ThemesDictionary Theme="Dark" />
<ui:ControlsDictionary />
</Application.Resources>
</Application>
```
> [!NOTE]
> You can find out how the Control Dictionary works here
## Segoe Fluent Icons
Not all icons available in WinUi 3 are in **Fluent UI System Icons**. Some of them require the **Segoe Fluent Icons** font.
According to the EULA of Segoe Fluent Icons we cannot ship a copy of it with this dll. Segoe Fluent Icons is installed by default on Windows 11, but if you want these icons in an application for Windows 10 and below, you must manually add the font to your application's resources.
[https://docs.microsoft.com/en-us/windows/apps/design/style/segoe-fluent-icons-font](https://docs.microsoft.com/en-us/windows/apps/design/style/segoe-fluent-icons-font)
[https://docs.microsoft.com/en-us/windows/apps/design/downloads/#fonts](https://docs.microsoft.com/en-us/windows/apps/design/downloads/#fonts)
In the `App.xaml` dictionaries, you can add an alternate path to the font
```xml
<Application
...
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml">
<Application.Resources>
<ui:ThemesDictionary Theme="Dark" />
<ui:ControlsDictionary />
<FontFamily x:Key="SegoeFluentIcons">pack://application:,,,/;component/Fonts/#Segoe Fluent Icons</FontFamily>
</Application.Resources>
</Application>
```
@@ -0,0 +1,34 @@
# WPF UI Docs
**WPF UI** is a library built for [Windows Presentation Foundation (WPF)](https://docs.microsoft.com/en-us/visualstudio/designers/getting-started-with-wpf) and the [C#](https://docs.microsoft.com/en-us/dotnet/csharp/) language.
To be able to work with them comfortably, you will need:
- [Visual Studio 2022 Community Edition](https://visualstudio.microsoft.com/vs/community/)
- .NET desktop development
_(Additional workload in Visual Studio)_
![NET development package](https://user-images.githubusercontent.com/13592821/191967842-118b8dc2-fb33-49c1-b9a9-162669b6e110.png)
> [!NOTE]
> Visual Studio 2022 and Visual Studio Code are two different programs. If you want to create WPF apps, it's possible to compile them in Visual Studio Code, however for comfortable work we recommend [Visual Studio 2022](https://visualstudio.microsoft.com/vs/community/) or [JetBrains Rider](https://www.jetbrains.com/rider/).
## Installation
You can install **WPF UI**, the library for the Windows Presentation Foundation framework, in several ways.
- Directly specify the `Wpf.Ui.dll` file in your application's project file (`.csproj`).
- Copy the library source code into your application codebase.
- Use the **NuGet** package manager.
We recommend using the **NuGet** package manager, it allows you to easily install and update your application dependencies.
More information on how to install **WPF UI** using **NuGet** [can be found here](/documentation/nuget.html).
## Extension for Visual Studio
Creators of **WPF UI** have prepared a special plugin that will automatically create a project based on **WPF UI**, Dependency Injection and MVVM, thanks to which you will quickly and easily start a new apps.
[Learn more about the WPF UI plug-in for Visual Studio 2022](/documentation/extension.html)
## Getting started
Once you have chosen how to install **WPF UI**, you can move on to creating your first app, more on this in [Getting Started](/documentation/getting-started.html).
@@ -0,0 +1 @@
# Menu
@@ -0,0 +1,323 @@
# NavigationView
`NavigationView` is a top-level navigation control that provides a collapsible navigation pane (the "hamburger menu") and a content area. It is the primary way to implement top-level navigation in your app.
> [!TIP]
> For a complete implementation example, see the [WPF UI Gallery](https://github.com/lepoco/wpfui/tree/main/src/Wpf.Ui.Gallery) application.
## Anatomy
The `NavigationView` control has several key areas:
- **Pane**: The area on the left or top that contains navigation items.
- **Header**: An area at the top of the content area, often used for a page title or a `BreadcrumbBar`.
- **Content Area**: The main area of the control where page content is displayed.
- **AutoSuggestBox**: An optional search box integrated into the navigation pane.
- **MenuItems**: The primary list of navigation items.
- **FooterMenuItems**: A secondary list of navigation items, typically for settings or about pages.
## Basic Usage
Define `NavigationView` in your XAML and add `NavigationViewItem` objects to the `MenuItems` and `FooterMenuItems` collections.
```xml
<ui:NavigationView
xmlns:pages="clr-namespace:YourApp.Views.Pages"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml">
<ui:NavigationView.MenuItems>
<ui:NavigationViewItem
Content="Home"
Icon="{ui:SymbolIcon Home24}"
TargetPageType="{x:Type pages:DashboardPage}" />
<ui:NavigationViewItem
Content="Data"
Icon="{ui:SymbolIcon DataHistogram24}"
TargetPageType="{x:Type pages:DataPage}" />
</ui:NavigationView.MenuItems>
<ui:NavigationView.FooterMenuItems>
<ui:NavigationViewItem
Content="Settings"
Icon="{ui:SymbolIcon Settings24}"
TargetPageType="{x:Type pages:SettingsPage}" />
</ui:NavigationView.FooterMenuItems>
</ui:NavigationView>
```
> [!NOTE]
> `TargetPageType` is a required property on `NavigationViewItem` that specifies the page to navigate to when the item is selected. The value must be a `System.Type`.
## Programmatic Navigation
You can navigate programmatically by calling the `Navigate` method with either the `Type` of the page or its `PageTag`.
```csharp
// Navigate by Type
MyNavigationView.Navigate(typeof(SettingsPage));
// Navigate by Tag
MyNavigationView.Navigate("settings");
```
To use tags, you must define a `PageTag` on the `NavigationViewItem`. If not defined, a tag is automatically generated from the `Content` property (e.g., "Settings Page" becomes "settingspage").
```xml
<ui:NavigationViewItem
Content="Settings"
PageTag="settings"
TargetPageType="{x:Type pages:SettingsPage}" />
```
### Back Navigation
`NavigationView` automatically handles back navigation. The back button is shown when `CanGoBack` is `true`. You can also call `GoBack()` programmatically.
```csharp
if (MyNavigationView.CanGoBack)
{
MyNavigationView.GoBack();
}
```
## Pane Display Mode
Control the visibility and behavior of the navigation pane with the `PaneDisplayMode` property.
- `Left`: The pane is always open on the left.
- `Top`: The pane is shown as a horizontal bar at the top.
- `LeftCompact`: The pane is collapsed to show only icons, and expands on hover or when the hamburger button is clicked.
- `LeftMinimal`: The pane is hidden and can be opened as an overlay.
```xml
<ui:NavigationView PaneDisplayMode="Top" />
```
You can also control the pane's open state with the `IsPaneOpen` property.
> [!TIP]
> To create a responsive layout that changes `PaneDisplayMode` based on window width, bind `PaneDisplayMode` to a property in your ViewModel and update it in the `Window.SizeChanged` event.
## Header
The `Header` property provides a content area above the navigation frame. It is commonly used with a `BreadcrumbBar` to show the user's location.
```xml
<ui:NavigationView>
<ui:NavigationView.Header>
<ui:BreadcrumbBar />
</ui:NavigationView.Header>
</ui:NavigationView>
```
The `BreadcrumbBar` will automatically sync with the `NavigationView`'s navigation history.
## MVVM Integration
For MVVM applications, it is recommended to use `INavigationService` and `IPageService` for navigation and page resolution.
### 1. Service Configuration
First, register the required services and your pages/ViewModels with your dependency injection container.
```csharp
// Using Microsoft.Extensions.DependencyInjection
Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
// Main window
services.AddScoped<IWindow, MainWindow>();
services.AddScoped<MainWindowViewModel>();
// Services
services.AddSingleton<INavigationService, NavigationService>();
services.AddSingleton<IPageService, PageService>();
// Pages and ViewModels
services.AddScoped<DashboardPage>();
services.AddScoped<DashboardViewModel>();
services.AddScoped<SettingsPage>();
services.AddScoped<SettingsViewModel>();
}).Build();
```
### 2. ViewModel Setup
In your `MainWindowViewModel`, define collections for your navigation items and bind them to the `NavigationView`.
```csharp
public partial class MainWindowViewModel : ObservableObject
{
[ObservableProperty]
private ICollection<object> _menuItems = new ObservableCollection<object>();
[ObservableProperty]
private ICollection<object> _footerMenuItems = new ObservableCollection<object>();
public MainWindowViewModel()
{
MenuItems = new ObservableCollection<object>
{
new NavigationViewItem("Home", SymbolRegular.Home24, typeof(DashboardPage)),
new NavigationViewItem("Data", SymbolRegular.DataHistogram24, typeof(DataPage))
};
FooterMenuItems = new ObservableCollection<object>
{
new NavigationViewItem("Settings", SymbolRegular.Settings24, typeof(SettingsPage))
};
}
}
```
### 3. View Setup
In your `MainWindow.xaml`, bind the `MenuItemsSource` and `FooterMenuItemsSource` properties to the collections in your ViewModel. Then, attach the `INavigationService`.
```xml
<ui:NavigationView
x:Name="RootNavigationView"
MenuItemsSource="{Binding MenuItems}"
FooterMenuItemsSource="{Binding FooterMenuItems}" />
```
```csharp
public partial class MainWindow : IWindow
{
public MainWindow(
MainWindowViewModel viewModel,
INavigationService navigationService,
IPageService pageService
)
{
ViewModel = viewModel;
DataContext = this;
InitializeComponent();
// Attach the service to the NavigationView
navigationService.SetNavigationControl(RootNavigationView);
// You can also set the page service, which is required for some functionalities
RootNavigationView.SetPageService(pageService);
}
public MainWindowViewModel ViewModel { get; }
}
```
### 4. Navigating from a ViewModel
Inject `INavigationService` into any ViewModel and use it to navigate.
```csharp
public partial class DashboardViewModel : ObservableObject
{
private readonly INavigationService _navigationService;
public DashboardViewModel(INavigationService navigationService)
{
_navigationService = navigationService;
}
[RelayCommand]
private void OnGoToSettings()
{
_navigationService.Navigate(typeof(SettingsPage));
}
}
```
## Navigation Events
`NavigationView` provides several events to hook into the navigation lifecycle:
- `Navigating`: Occurs before navigation starts. Can be cancelled.
- `Navigated`: Occurs after navigation is complete.
- `SelectionChanged`: Occurs when a `NavigationViewItem` is selected.
```csharp
private void OnNavigating(NavigationView sender, NavigatingCancelEventArgs args)
{
// Don't navigate to settings if the user is not an admin
if (args.PageType == typeof(SettingsPage) && !_isAdmin)
{
args.Cancel = true;
}
}
```
## Navigation-Aware Pages
Implement `INavigationAware` on your page's code-behind or `INavigableView<T>` on your ViewModel to receive navigation events directly.
### INavigationAware
This interface is ideal for code-behind scenarios.
```csharp
public partial class MyPage : INavigationAware
{
public void OnNavigatedTo()
{
// Page was navigated to
}
public void OnNavigatedFrom()
{
// Page was navigated away from
}
}
```
### `INavigableView<T>`
This interface is designed for MVVM. Your page must inherit from `INavigableView<T>` where `T` is its ViewModel. The ViewModel will then receive the navigation calls.
**Page:**
```csharp
[GalleryPage("My Page", SymbolRegular.Page24)]
public partial class MyPage : INavigableView<MyViewModel>
{
public MyViewModel ViewModel { get; }
public MyPage(MyViewModel viewModel)
{
ViewModel = viewModel;
DataContext = this;
InitializeComponent();
}
}
```
**ViewModel:**
```csharp
public partial class MyViewModel : ObservableObject, INavigationAware
{
public void OnNavigatedTo()
{
// Page was navigated to
}
public void OnNavigatedFrom()
{
// Page was navigated away from
}
}
```
> [!IMPORTANT]
> For `INavigableView<T>` to work, your page must have a public `ViewModel` property that returns an instance of the ViewModel.
## History and Caching
`NavigationView` maintains a navigation history.
- `History`: A collection of `Page` instances that have been visited.
- `CacheHistory`: The number of pages to keep in memory. The default is `0`. Set to a value greater than 0 to cache pages. When a cached page is navigated to, its previous state is preserved.
```xml
<ui:NavigationView CacheHistory="5" />
```
> [!CAUTION]
> Caching pages increases memory consumption. Use it only for pages that are expensive to create or where preserving state is critical. Avoid caching pages that display frequently changing data.
@@ -0,0 +1,31 @@
# NuGet package for WPF UI
## What's NuGet?
NuGet is a free, open-source package management system for the Microsoft .NET platform. It simplifies the process of finding, installing, and managing third-party libraries and tools in .NET projects. NuGet allows developers to easily add functionality to their projects without having to manually download and reference external libraries. It also provides a way for developers to publish and share their own packages with the .NET community. Overall, NuGet makes it easier to manage dependencies in .NET projects and helps to improve productivity for developers.
- [Read more here](https://learn.microsoft.com/en-us/nuget/what-is-nuget)
- [How to install NuGet packages](https://learn.microsoft.com/en-us/nuget/consume-packages/overview-and-workflow#ways-to-install-a-nuget-package=)
- [Install and manage packages in Visual Studio using the NuGet Package Manager](https://learn.microsoft.com/en-us/nuget/consume-packages/install-use-packages-visual-studio)
## How to install **WPF UI** in Visual Studio using the NuGet Package Manager?
### 1. Create new WPF project
![New project in Visual Studio](https://user-images.githubusercontent.com/13592821/192056284-0efcefa6-990e-4ef6-ab44-5746e4bf66ed.png)
### 2. Open _Manage NuGet Packages_ window via solution explorer
![Manage NuGet Packages](https://user-images.githubusercontent.com/13592821/192056354-4f5a46c1-d02f-4c7b-8822-c8cd6f105ed1.png)
### 3. In the _Browse_ tab, enter "**WPF-UI**"
![Browse tab in NuGet](https://user-images.githubusercontent.com/13592821/192056603-d9c48b4d-b9f1-485a-80cf-9fd27d8e55d7.png)
### 4. Install **WPF-UI** package
![Package installed](https://user-images.githubusercontent.com/13592821/192056761-186336dd-3aed-450c-b036-bbfdc6b73e74.png)
# Done!
Package installed, to learn more, go to the [**Getting started**](/documentation/getting-started.html) page.
@@ -0,0 +1,5 @@
# WPF UI Releases
| Version | Is supported |
| ------- | ------------ |
| 3.0.0 | Yes |
@@ -0,0 +1,41 @@
# SymbolIcon
`SymbolIcon` is a control responsible for rendering icons.
### Implementation
```csharp
class Wpf.Ui.Controls.SymbolIcon
```
## Exposes
```csharp
// Gets or sets displayed symbol
SymbolIcon.Symbol = SymbolRegular.Empty;
```
```csharp
// Defines whether or not we should use the SymbolFilled
SymbolIcon.Filled = false;
```
```csharp
// Icon foreground
SymbolIcon.Foreground = Brushes.White;
```
```csharp
// Icon size
SymbolIcon.FontSize = 16;
```
### How to use
```xml
<ui:SymbolIcon
Symbol="Fluent24"
Filled="False"
FontSize="16"
Foreground="White"/>
```
@@ -0,0 +1,98 @@
# SystemThemeWatcher
`SystemThemeWatcher` automatically synchronizes the application's theme, accent color, and window backdrop with the current Windows theme settings. It listens for system-level changes and applies them to your application in real-time.
> [!TIP]
> The simplest way to enable system theme tracking is to call `SystemThemeWatcher.Watch(this);` in your main window's constructor.
## How It Works
`SystemThemeWatcher` attaches a hook to a window's message procedure (`WndProc`) and listens for the `WM_WININICHANGE` system message. When Windows broadcasts this message (e.g., when the user changes from light to dark mode), the watcher automatically calls `ApplicationThemeManager.ApplySystemTheme()` to update your application's appearance.
## Basic Usage
Enable theme watching in your window's constructor. This will use the default `Mica` backdrop and update accent colors.
```csharp
using Wpf.Ui.Appearance;
public partial class MainWindow : System.Windows.Window
{
public MainWindow()
{
// This will apply the system theme, accent, and default backdrop.
SystemThemeWatcher.Watch(this);
InitializeComponent();
}
}
```
## Customization
You can customize the backdrop effect and control whether the accent color is updated.
### Window Backdrop
Specify the `WindowBackdropType` to apply when the theme changes.
```csharp
SystemThemeWatcher.Watch(
this,
WindowBackdropType.Acrylic // Use Acrylic backdrop
);
```
Available backdrop types:
- `None`: No backdrop effect.
- `Auto`: Automatically selects the appropriate backdrop.
- `Mica`: The default Windows 11 Mica effect.
- `Acrylic`: The semi-transparent Acrylic effect.
- `Tabbed`: A blurred wallpaper effect available in recent Windows 11 versions.
### Accent Color Updates
You can prevent the watcher from changing the application's accent color.
```csharp
SystemThemeWatcher.Watch(
this,
updateAccents: false // Theme will change, but accent color will not
);
```
## Stop Watching
To stop a window from responding to system theme changes, use the `UnWatch` method.
```csharp
SystemThemeWatcher.UnWatch(this);
```
> [!IMPORTANT]
> Do not call `UnWatch` on a window that has not been loaded, as it will throw an `InvalidOperationException`. It is safe to call `Watch` on a window that is not yet loaded.
## Dependency Injection Usage
If you are resolving your main window from a dependency injection container, you can start the watcher after the host is built.
```csharp
var host = Host.CreateDefaultBuilder()
.ConfigureServices(services =>
{
services.AddHostedService<ApplicationHostService>();
services.AddSingleton<MainWindow>();
// ... other services
}).Build();
await host.StartAsync();
var mainWindow = host.Services.GetRequiredService<MainWindow>();
// Watch the window after it's been created
SystemThemeWatcher.Watch(mainWindow);
```
> [!NOTE]
> `SystemThemeWatcher` works on a static, global basis. While you can `Watch` multiple windows, the theme and accent settings applied will be the same for all of them based on the parameters of the last `Watch` call that triggered an update.
@@ -0,0 +1,125 @@
# Application Themes
WPF UI provides a robust theming system that allows you to control your application's appearance, including support for light, dark, and high contrast modes. The `ApplicationThemeManager` class is the primary tool for managing themes at runtime.
> [!IMPORTANT]
> For theme changes to apply correctly, your colors and brushes should be referenced as `DynamicResource`.
## Setting the Initial Theme
The easiest way to set the initial theme is by using the `ThemesDictionary` in your `App.xaml`. This ensures that the correct theme resources are loaded at startup.
```xml
<Application
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ui:ThemesDictionary Theme="Light" />
<ui:ControlsDictionary />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
```
The `Theme` property on `ThemesDictionary` can be set to `Light` or `Dark`.
## Changing the Theme at Runtime
Use the `ApplicationThemeManager.Apply()` method to change the theme while the application is running.
```csharp
using Wpf.Ui.Appearance;
using Wpf.Ui.Controls;
// Apply the Light theme with a Mica backdrop
ApplicationThemeManager.Apply(
ApplicationTheme.Light,
WindowBackdropType.Mica
);
```
### `ApplicationTheme` Enum
This enum specifies the theme to apply:
- `Light`: The standard light theme.
- `Dark`: The standard dark theme.
- `HighContrast`: Automatically selects the appropriate Windows High Contrast theme.
## System Theme Integration
You can synchronize your application's theme with the current Windows theme settings.
### One-Time Sync
To apply the current system theme once, use `ApplySystemTheme()`.
```csharp
// Apply the current Windows theme (light or dark)
ApplicationThemeManager.ApplySystemTheme();
```
### Automatic Tracking
For continuous synchronization, use the `SystemThemeWatcher`. It automatically updates your app's theme and accent color when the user changes their Windows settings. See the [SystemThemeWatcher documentation](./system-theme-watcher.md) for more details.
```csharp
using Wpf.Ui.Appearance;
public partial class MainWindow : System.Windows.Window
{
public MainWindow()
{
// Watch for system theme changes
SystemThemeWatcher.Watch(this);
InitializeComponent();
}
}
```
## Reading the Current Theme
You can get the current application and system themes at any time.
- `ApplicationThemeManager.GetAppTheme()`: Returns the current `ApplicationTheme` (Light, Dark, or HighContrast).
- `ApplicationThemeManager.GetSystemTheme()`: Returns the current `SystemTheme`.
```csharp
ApplicationTheme currentAppTheme = ApplicationThemeManager.GetAppTheme();
SystemTheme currentSystemTheme = ApplicationThemeManager.GetSystemTheme();
if (currentAppTheme == ApplicationTheme.Dark)
{
// ...
}
```
### `SystemTheme` Enum
This enum represents the actual theme reported by Windows, including decorative themes like `Glow`, `CapturedMotion`, and `Sunrise`. `ApplicationThemeManager` maps these to either `Light` or `Dark`.
## High Contrast Themes
WPF UI automatically handles Windows High Contrast themes. When a high contrast mode is detected, `ApplicationThemeManager` loads the appropriate high contrast resource dictionary (`HC1`, `HC2`, `HCBlack`, or `HCWhite`).
- `ApplicationThemeManager.IsHighContrast()`: Checks if the application is currently in a high contrast theme.
- `ApplicationThemeManager.IsSystemHighContrast()`: Checks if Windows is currently in a high contrast mode.
## Theme Changed Event
The `ApplicationThemeManager.Changed` event is triggered whenever the application's theme is successfully changed.
```csharp
ApplicationThemeManager.Changed += (currentTheme, currentAccent) =>
{
Debug.WriteLine($"Theme changed to {currentTheme} with accent {currentAccent}");
};
```
This event is useful for applying custom logic after a theme change, such as updating graphics or non-WPF UI elements.
> [!TIP]
> The `Changed` event is fired by both manual `Apply()` calls and automatic updates from `SystemThemeWatcher`, providing a single place to react to any theme change.