Skip to content

TwilightLemon/FluentWpfCore

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

15 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

FluentWpfCore (Preview)

A WPF library providing core Fluent Design controls, materials, and visual effects.
README_Zh-CN.md

C# WPF GitHub Repo stars

✨ Features

πŸͺŸ Window Material System

  • Multiple material types β€” Acrylic, Mica, MicaAlt and other modern window materials
  • Flexible combination β€” combine material effects with rounded corners, shadows, and DWM animations
  • Cross-version compatibility β€” supports older Windows 10 Composition APIs and the Windows 11 System Backdrop APIs
  • Dark mode support β€” built-in light/dark mode switching (primarily for Mica effects)
  • Custom composition color β€” customize background color and opacity for Acrylic

🎨 Enhanced Basic Controls

  • FluentPopup β€” popup with acrylic background, rounded corners, shadow and sliding animations
  • SmoothScrollViewer β€” provides smooth, fluid scrolling
  • Fluent-style templates β€” modern styles and templates for Menu, ContextMenu and ToolTip

πŸ”§ Low-level Capabilities

  • DWM integration β€” effects are rendered via DWM; best results on Windows 11
  • WindowChrome compatibility β€” works with WPF's native WindowChrome
  • Theme-agnostic β€” does not force a UI style; integrates with any existing theme

FluentWpfCore does not ship a full set of high-level UI controls. Instead, it provides low-level capabilities compatible with any theme so you can add modern visual effects without changing your existing UI style.

πŸ”§ System Requirements

  • Windows 10 1809 or later (some features require Windows 11)

Feature support

Feature Windows 10 1809+ Windows 11
Acrylic (Composition) βœ… βœ…
Acrylic (System Backdrop) ❌ βœ…
Mica ❌ βœ…
Window corners ❌ βœ…
DWM animations βœ… βœ…

Supported .NET versions

  • .NET 10.0 Windows
  • .NET 8.0 Windows
  • .NET 6.0 Windows
  • .NET Framework 4.5 ~ 4.8

πŸ“¦ Installation

NuGet Package Manager

Install-Package FluentWpfCore

.NET CLI

dotnet add package FluentWpfCore

PackageReference

<PackageReference Include="FluentWpfCore" Version="1.0.0" />

πŸ“– Usage Guide

Window Materials

FluentWpfCore provides comprehensive window material support (Acrylic, Mica, etc.) and combinations of DWM effects. Use combinations of the following categories:

Category Options Notes
Window material Acrylic\Mica\MicaAlt Options: dark mode, composition color, keep-acrylic-when-unfocused (Acrylic)
Corner style Round\SmallRound\DoNotRound\Default
Window shadow On\Off Tied to corner style and DWM availability

Example β€” creating an Acrylic window with a custom composition color, rounded corners, shadow and DWM animation, removing the native title bar and buttons:

<Window x:Class="YourApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:fluent="https://github.com/TwilightLemon/FluentWpfCore"
        Title="MainWindow"
        Width="800"
        Height="450"

        Background="Transparent"
        fluent:DwmAnimation.EnableDwmAnimation="True"
        fluent:WindowMaterial.WindowCorner="Round">
    
    <Window.Resources>
        <WindowChrome x:Key="windowChrome" CaptionHeight="32" />
    </Window.Resources>
    
    <fluent:WindowMaterial.Material>
        <fluent:WindowMaterial x:Name="windowMaterial"
                               CompositonColor="#CC6699FF"
                               IsDarkMode="False"
                               MaterialMode="Acrylic"
                               UseWindowComposition="True"
                               WindowChromeEx="{StaticResource windowChrome}" />
    </fluent:WindowMaterial.Material>
    
    <!--Content-->
</Window>
Property Summary
Property Type Description
MaterialMode MaterialType Material type: None, Acrylic, Mica, MicaAlt
IsDarkMode bool Whether to use dark mode (relevant to Mica/MicaAlt; less pronounced for Acrylic)
UseWindowComposition bool Use window composition APIs (Windows 10 1809+; applicable to Acrylic)
WindowChromeEx WindowChrome Custom WindowChrome configuration
CompositonColor Color Composition color used by Acrylic when UseWindowComposition=true

Window Corners

Forces Windows 11-style rounded corners on a window to override WPF or DWM defaults. Enabling rounded corners can also bring window shadow (DWM-dependent, Windows 11 only) and borders.

You can enable corners in XAML or on the native HWND in code:

<Window xmlns:fluent="https://github.com/TwilightLemon/FluentWpfCore"
        fluent:WindowMaterial.WindowCorner="Round"
        ...>
using FluentWpfCore.Interop;
MaterialApis.SetWindowCorner(hwnd, corner);

Supported corner types:

  • Default β€” system default
  • DoNotRound β€” disable rounding
  • Round β€” rounded corners
  • RoundSmall β€” small rounded corners

Recommended scenarios:

  • Use corners when relying on Acrylic with UseWindowComposition=true because DWM defaults may produce square corners without shadow
  • Control the corner style of ToolTip, Popup and other transient windows
  • Customize window border styling even when using WindowChrome or AllowsTransparency

DWM Animations

Enable native window animations (maximize/minimize) while removing the native title bar and buttons:

<Window xmlns:fluent="https://github.com/TwilightLemon/FluentWpfCore"
        fluent:DwmAnimation.EnableDwmAnimation="True"
        ...>

Note: enabling DWM animations will ignore Window.ResizeMode. If you need ResizeMode="NoResize", set WindowChrome.ResizeBorderThickness="0" instead.

Combining Effects

You can combine the above behaviors freely. Examples:

Plain Mica native window
<Window Background="Transparent"
        ...>
    <fluent:WindowMaterial.Material>
        <fluent:WindowMaterial IsDarkMode="False"
                               MaterialMode="Mica"/>
    </fluent:WindowMaterial.Material>
</Window>

This enables Mica as the background while keeping native title bar, buttons, borders and animations.

Mica window with a custom title bar while preserving native animations and borders
<Window Background="Transparent"
        fluent:DwmAnimation.EnableDwmAnimation="True"
        ...>
    <Window.Resources>
        <WindowChrome x:Key="windowChrome" CaptionHeight="32" />
    </Window.Resources>
    <fluent:WindowMaterial.Material>
        <fluent:WindowMaterial IsDarkMode="False"
                               MaterialMode="Mica"
                               WindowChromeEx="{StaticResource windowChrome}"/>
    </fluent:WindowMaterial.Material>
</Window>
Keep Acrylic when unfocused, with rounded corners and shadow
<Window Background="Transparent"
        fluent:DwmAnimation.EnableDwmAnimation="True"
        fluent:WindowMaterial.WindowCorner="Round">
    <Window.Resources>
        <WindowChrome x:Key="windowChrome" CaptionHeight="32" />
    </Window.Resources>
    <fluent:WindowMaterial.Material>
        <fluent:WindowMaterial x:Name="windowMaterial"
                               CompositonColor="#CC6699FF"
                               IsDarkMode="False"
                               MaterialMode="Acrylic"
                               UseWindowComposition="True"
                               WindowChromeEx="{StaticResource windowChrome}"/>
    </fluent:WindowMaterial.Material>
</Window>

When UseWindowComposition="True" a different API path is used to enable legacy material effects on Windows 10.

Acrylic window with square corners and no shadow
<Window Background="Transparent"
        fluent:DwmAnimation.EnableDwmAnimation="True">
    <Window.Resources>
        <WindowChrome x:Key="windowChrome" CaptionHeight="32" />
    </Window.Resources>
    <fluent:WindowMaterial.Material>
        <fluent:WindowMaterial x:Name="windowMaterial"
                               CompositonColor="#CC6699FF"
                               IsDarkMode="False"
                               MaterialMode="Acrylic"
                               UseWindowComposition="True"
                               WindowChromeEx="{StaticResource windowChrome}"/>
    </fluent:WindowMaterial.Material>
</Window>

FluentPopup

FluentPopup is an enhanced popup control with an acrylic background, rounded corners, shadow and custom enter/exit animations, and optional follow-window-moving behavior:

<Button x:Name="ShowPopupBtn" Content="Show Popup" />

<fluent:FluentPopup x:Name="testPopup"
                    Background="{DynamicResource PopupBackgroundColor}"
                    ExtPopupAnimation="SlideDown"
                    FollowWindowMoving="False"
                    Placement="Bottom"
                    WindowCorner="Round"
                    PlacementTarget="{Binding ElementName=ShowPopupBtn}"
                    StaysOpen="False">
    <Grid Width="180" Height="120">
        <TextBlock Text="Hello FluentWpfCore!"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center" />
    </Grid>
</fluent:FluentPopup>

Properties

Property Type Description
Background SolidColorBrush Popup background color (only solid colors supported)
ExtPopupAnimation ExPopupAnimation Animation type: None, SlideUp, SlideDown
FollowWindowMoving bool Whether the popup follows window movement
WindowCorner WindowCorner Corner style for the popup

If you need non-solid backgrounds, keep the popup background transparent and provide custom visuals inside the popup content.

SmoothScrollViewer

Provides a smooth scrolling experience with customizable physics models and support for mouse wheel, touchpad, touch and pen input:

<fluent:SmoothScrollViewer>
    <StackPanel>
        <!-- content -->
    </StackPanel>
</fluent:SmoothScrollViewer>

Properties

Property Type Default Description
IsEnableSmoothScrolling bool true Enable or disable smooth scrolling animation
PreferredScrollOrientation Orientation Vertical Preferred scroll direction: Vertical or Horizontal
AllowTogglePreferredScrollOrientationByShiftKey bool true Allow toggling scroll orientation by holding Shift key
Physics IScrollPhysics DefaultScrollPhysics Scrolling physics model that controls animation behavior

Scroll Physics Model

SmoothScrollViewer uses a pluggable physics model through the IScrollPhysics interface, allowing you to customize scrolling behavior. The default implementation is DefaultScrollPhysics, which provides two distinct modes:

Precision Mode (Touchpad)

For touchpad/touch input, uses smooth interpolation to follow the target offset:

  • LerpFactor (double, default: 0.5, range: 0~1) β€” Interpolation coefficient; higher values make scrolling reach the target faster
Momentum Mode (Mouse Wheel)

For mouse wheel input, uses velocity-based physics with friction:

  • MinVelocityFactor (double, default: 1.2, range: 1~2) β€” Initial velocity multiplier; higher values result in faster initial speed and longer scroll distance
  • Friction (double, default: 0.92, range: 0~1) β€” Velocity decay coefficient; lower values make scrolling stop faster

The physics model automatically detects input type and switches between modes. Velocity factor dynamically adjusts based on scroll interval timing for optimal feel.

Usage Examples

Basic usage
<fluent:SmoothScrollViewer>
    <StackPanel>
        <TextBlock Text="Item 1" Height="100" />
        <TextBlock Text="Item 2" Height="100" />
        <TextBlock Text="Item 3" Height="100" />
        <!-- more items -->
    </StackPanel>
</fluent:SmoothScrollViewer>
Customize scroll physics
<fluent:SmoothScrollViewer>
    <fluent:SmoothScrollViewer.Physics>
        <fluent:DefaultScrollPhysics MinVelocityFactor="1.5"
                                     Friction="0.85"
                                     LerpFactor="0.6" />
    </fluent:SmoothScrollViewer.Physics>
    <StackPanel>
        <!-- content -->
    </StackPanel>
</fluent:SmoothScrollViewer>
Configure scroll orientation
<!-- Horizontal scrolling by default -->
<fluent:SmoothScrollViewer PreferredScrollOrientation="Horizontal"
                           HorizontalScrollBarVisibility="Auto"
                           VerticalScrollBarVisibility="Disabled">
    <StackPanel Orientation="Horizontal">
        <!-- content -->
    </StackPanel>
</fluent:SmoothScrollViewer>
Toggle between vertical and horizontal with Shift key
<fluent:SmoothScrollViewer AllowTogglePreferredScrollOrientationByShiftKey="True"
                           HorizontalScrollBarVisibility="Auto"
                           VerticalScrollBarVisibility="Auto">
    <!-- Hold Shift while scrolling to switch orientation -->
    <Grid>
        <!-- content -->
    </Grid>
</fluent:SmoothScrollViewer>
Temporarily disable smooth scrolling
<fluent:SmoothScrollViewer IsEnableSmoothScrolling="False">
    <!-- Falls back to standard ScrollViewer behavior -->
    <StackPanel>
        <!-- content -->
    </StackPanel>
</fluent:SmoothScrollViewer>
Use with ItemsControl for large lists
<fluent:SmoothScrollViewer>
    <ItemsControl ItemsSource="{Binding Items}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Border Height="50" Background="LightGray" Margin="5">
                    <TextBlock Text="{Binding}" VerticalAlignment="Center" Margin="10" />
                </Border>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</fluent:SmoothScrollViewer>
Custom physics implementation

You can implement your own physics model by implementing the IScrollPhysics interface:

public class CustomScrollPhysics : IScrollPhysics
{
    public bool IsStable { get; private set; }
    
    public void OnScroll(double currentOffset, double delta, bool isPrecision, 
                         double minOffset, double maxOffset, int timeIntervalMs)
    {
        // Handle scroll input
        IsStable = false;
    }
    
    public double Update(double currentOffset, double dt, 
                         double minOffset, double maxOffset)
    {
        // Calculate and return new offset
        // Set IsStable = true when animation should stop
        return newOffset;
    }
}

Then apply it to the SmoothScrollViewer:

smoothScrollViewer.Physics = new CustomScrollPhysics();

Fluent-style Menu

Since menu styling involves templates and resources, include the theme resources first.

1. Merge resource dictionary

In App.xaml merge the FluentWpfCore theme resources:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <!-- FluentWpfCore default theme -->
            <ResourceDictionary Source="pack://application:,,,/FluentWpfCore;component/Themes/Generic.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <SolidColorBrush x:Key="ForegroundColor" Color="#FF0E0E0E" />
        
        <!-- Overrideable colors -->
        <SolidColorBrush x:Key="AccentColor" Color="#FFFF8541" />
    </ResourceDictionary>
</Application.Resources>
Overrideable color key Description
AccentColor Accent color
PopupBackgroundColor Popup background color
MaskColor Mask color used for hover highlights

2. Apply global styles (optional)

<!-- ContextMenu style -->
<Style BasedOn="{StaticResource FluentContextMenuStyle}" TargetType="{x:Type ContextMenu}">
    <Setter Property="Foreground" Value="{DynamicResource ForegroundColor}" />
</Style>

<!-- MenuItem style -->
<Style BasedOn="{StaticResource FluentMenuItemStyle}" TargetType="MenuItem">
    <Setter Property="Height" Value="36" />
    <Setter Property="Foreground" Value="{DynamicResource ForegroundColor}" />
    <Setter Property="VerticalContentAlignment" Value="Center" />
</Style>

<!-- TextBox ContextMenu -->
<Style TargetType="TextBox">
    <Setter Property="ContextMenu" Value="{StaticResource FluentTextBoxContextMenu}" />
</Style>

<!-- ToolTip style -->
<Style TargetType="{x:Type ToolTip}">
    <Setter Property="fluent:FluentStyle.UseFluentStyle" Value="True" />
    <Setter Property="Background" Value="{DynamicResource PopupBackgroundColor}" />
    <Setter Property="Foreground" Value="{DynamicResource ForegroundColor}" />
</Style>

Menu example

<Menu Background="Transparent"
      Foreground="{DynamicResource ForegroundColor}"
      WindowChrome.IsHitTestVisibleInChrome="True">
    <MenuItem Header="_File">
        <MenuItem Header="_New" />
        <MenuItem Header="_Open" />
        <MenuItem Header="_Recent Files">
            <MenuItem Header="File1.txt" />
        </MenuItem>
    </MenuItem>
    <MenuItem Header="_Help" />
</Menu>

ContextMenu example

<TextBlock Text="Right Click Me">
    <TextBlock.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Menu Item 1"
                      Icon="πŸ“‹"
                      InputGestureText="Ctrl+C" />
            <MenuItem Header="Menu Item 2">
                <MenuItem Header="Child Item 1" />
                <MenuItem Header="Child Item 2" />
                <MenuItem Header="Child Item 3"
                          IsCheckable="True"
                          IsChecked="True" />
            </MenuItem>
            <MenuItem Header="Menu Item 3" />
        </ContextMenu>
    </TextBlock.ContextMenu>
</TextBlock>

ToolTip example

<TextBlock Text="Hover over me"
           ToolTipService.ShowDuration="3000">
    <TextBlock.ToolTip>
        <ToolTip>
            <TextBlock Text="This is a FluentWpfCore ToolTip!"/>
        </ToolTip>
    </TextBlock.ToolTip>
</TextBlock>

Or simply:

<TextBlock Text="Hover over me"
           ToolTip="This is a FluentWpfCore ToolTip!"/>

🀝 Contributing

Issues and pull requests are welcome!

πŸ“„ License

This project is open source under the MIT license.

πŸ™ Thanks

Thanks to all contributors to FluentWpfCore!

🧷 Related Tutorials


Made with ❀️ by TwilightLemon

About

A WPF library providing core Fluent Design controls, materials, and visual effects.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages