Get started with WPFDevelopers controls in your WPF project in three steps.
WPFDevelopers covers the full spectrum from .NET Framework 4.0 to .NET 10:
| Framework Family | Specific Versions |
|---|---|
| .NET Framework | net40, net45, net451, net452, net46, net461, net462, net47, net471, net472, net48, net481 |
| .NET Core | netcoreapp3.0, netcoreapp3.1 |
| .NET 5+ | net5.0-windows, net6.0-windows, net7.0-windows, net8.0-windows, net9.0-windows, net10.0-windows |
- Visual Studio 2026
- .NET Framework 4.0 or later / .NET Core 3.0 or later
If you need to use the map control, start with:
This guide is separated from the general quick-start content because MapView is a larger, feature-rich component with dedicated examples and configuration guidance.
Install via NuGet Package Manager or Package Manager Console:
Install-Package WPFDevelopersNote: For the latest features, use the preview package:
Install-Package WPFDevelopers -Pre
Or in Visual Studio: right-click your project β Manage NuGet Packages β search WPFDevelopers β Install.
Add the WD namespace and theme resources in App.xaml:
<Application x:Class="YourApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- 1. Theme must be imported first -->
<ResourceDictionary Source="pack://application:,,,/WPFDevelopers;component/Themes/Theme.xaml" />
<!-- 2. wd:Resources must come AFTER Theme.xaml -->
<wd:Resources Radius="4" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application><wd:Resources /> supports the following modes:
| Configuration | Effect |
|---|---|
<wd:Resources Radius="4" /> |
Default Light theme, 4px control corner radius (follows system Light/Dark on Windows 10+) |
<wd:Resources Theme="Light" Radius="4" /> |
Fixed light theme, 4px corner radius |
<wd:Resources Theme="Dark" Radius="4" /> |
Fixed dark theme, 4px corner radius |
<wd:Resources Color="Fuchsia" Radius="4" /> |
Custom theme color, 4px corner radius |
Tip: The
Radiusproperty controls the corner radius of controls. Windows 11 defaults to 4px, Windows 10 defaults to 0px. Adjust as needed.
Important:
wd:Resourcesmust be placed afterTheme.xamlin MergedDictionaries, otherwise the theme will not load correctly.
Declare the namespace in any XAML file:
xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"Then use WD controls:
<Window x:Class="YourApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"
Title="My App" Width="800" Height="600">
<Grid>
<wd:BallLoading Width="100" IsLoading="True" />
</Grid>
</Window>ColorPicker remains an inline panel. Its format dropdown selects RGB, HSL, or HEX directly; set ColorType to choose the initial format.
<wd:ColorPicker SelectedColor="{Binding AccentColor}" ColorType="HEX" />Set DisplayMode="Popup" on the same ColorPicker to show a clickable swatch that opens the panel. The default, DisplayMode="Inline", preserves the existing inline display:
<wd:ColorPicker DisplayMode="Popup" SelectedColor="{Binding AccentColor}" />
<wd:ColorPicker DisplayMode="Popup" SelectedColor="{Binding AccentColor}"
ShowColorText="True"
SwatchSize="24"
ColorType="HEX" />SelectedColoris aColorand binds two-way by default. Changes are applied immediately, without confirmation.ShowColorTextdefaults toFalse. Enable it to display HEX beside the swatch:#RRGGBBfor opaque colors, or#AARRGGBBotherwise.SwatchSizeis the swatch side length, defaulting to 18. Use positive values such as 24 or 32; trigger dimensions also include padding and borders.IsDropDownOpensupports two-way binding. Click outside or press Esc to close; F4 or Alt+Down toggles the popup. Space opens it when the trigger has focus.- Mouse activation opens the panel on release so the popup can capture outside clicks. Outside-click dismissal remains available after changing formats.
ShowColorText,SwatchSize, andIsDropDownOpenapply to Popup mode; Inline mode cannot open a popup. SwitchingDisplayModeat runtime closes the popup and preserves the color and format.SelectedColorChangedis a bubbling color-change event. Both modes share the color panel and theme resources. In Popup mode,Width,Height, andPaddingconfigure the trigger, not the inner panel.
GridSplitter is a standard WPF control and does not require the wd: prefix. After configuring the theme above, its default style has a transparent background and a centered three-dot grip. Hovering hides the dots and highlights the splitter with the theme color; leaving restores the grip.
The three-dot grip requires a library version containing this change. Earlier NuGet packages may not include this style.
Place the splitter in a dedicated Auto column and set Width and ResizeDirection="Columns":
<Grid Height="180">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="60" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" MinWidth="60" />
</Grid.ColumnDefinitions>
<Border Background="{DynamicResource WD.PrimaryMouseOverBrush}">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Left" />
</Border>
<GridSplitter
Grid.Column="1"
Width="5"
Margin="2,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ResizeDirection="Columns"
ResizeBehavior="PreviousAndNext"
ShowsPreview="True" />
<Border Grid.Column="2" Background="{DynamicResource WD.PrimaryMouseOverBrush}">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Right" />
</Border>
</Grid>Place the splitter in a dedicated Auto row and set Height and ResizeDirection="Rows". The three-dot grip rotates to a horizontal arrangement:
<Grid Height="240">
<Grid.RowDefinitions>
<RowDefinition Height="*" MinHeight="40" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" MinHeight="40" />
</Grid.RowDefinitions>
<Border Background="{DynamicResource WD.PrimaryMouseOverBrush}">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Top" />
</Border>
<GridSplitter
Grid.Row="1"
Height="5"
Margin="0,2"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ResizeDirection="Rows"
ResizeBehavior="PreviousAndNext"
ShowsPreview="False" />
<Border Grid.Row="2" Background="{DynamicResource WD.PrimaryMouseOverBrush}">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="Bottom" />
</Border>
</Grid>Configuration notes:
- Set
ResizeDirectionexplicitly:Columnsresizes adjacent columns;Rowsresizes adjacent rows. The current grip style rotates through theRowstrigger, not through the effective direction inferred byAuto. ResizeBehavior="PreviousAndNext"resizes the rows or columns on either side of the splitter, matching the dedicated row/column layouts above.ShowsPreview="True"previews the resize and applies it on release;Falseresizes immediately. Preview mode requires anAdornerLayerin the visual tree, which standard WPF windows normally provide.- Set
MinWidth/MinHeighton content columns/rows to prevent panes from becoming too small. Margin="2,0"adds 2 DIPs on each side;Margin="0,2"adds 2 DIPs above and below. Margins on neighboring containers add to this spacing, so prefer configuring the gap on the splitter alone. The transparent background remains hit-testable for dragging.Foregroundcontrols the dot color; the hover background uses the theme resourceWD.PrimaryBrush.
Find the interactive demo under Basic β GridSplitter in the sample application. See GridSplitterExample.xaml for the source.
wd:MarkdownViewer renders Markdown content as rich text in WPF, which is ideal for README files, help documentation, changelogs, and in-app knowledge content. It supports common Markdown elements such as headings, lists, blockquotes, code blocks, tables, links, and images.
The most commonly used property is Markdown, which accepts the Markdown text directly:
<Grid>
<wd:MarkdownViewer
Margin="12"
Padding="12"
FontSize="14"
Markdown="## Hello Markdown This is **WPFDevelopers** MarkdownViewer." />
</Grid>You can also bind the content dynamically:
<wd:MarkdownViewer
Margin="12"
Padding="12"
Markdown="{Binding MarkdownText}" />public string MarkdownText { get; } = "# WPFDevelopers\n\n- Supports headings\n- Supports lists\n- Supports code blocks";Common usage notes:
Markdown: the Markdown text to renderPadding: spacing inside the content areaFontSize,FontFamily,Foreground: text style customization
The complete sample and interactive demo are available here:
src/WPFDevelopers.Samples.Shared/ExampleViews/MarkdownViewerExample.xamlsrc/WPFDevelopers.Samples.Shared/ExampleViews/MarkdownViewerExample.xaml.cs
If you need to display a README, help document, release notes, or internal documentation in your app, MarkdownViewer is the most direct option.
<!-- Loading animation -->
<wd:BallLoading Width="100" IsLoading="{Binding IsLoading}" />
<!-- Drawer panel -->
<wd:Drawer x:Name="DrawerTop" Position="Top">
<wd:Drawer.Header><TextBlock Text="Title" FontSize="16" /></wd:Drawer.Header>
<wd:Drawer.Content><TextBlock Text="Content" /></wd:Drawer.Content>
</wd:Drawer>
<!-- Multi-select ComboBox -->
<wd:MultiSelectComboBox ItemsSource="{Binding Items}" ShowType="Tag">
<wd:MultiSelectComboBoxItem Content="Option 1" />
<wd:MultiSelectComboBoxItem Content="Option 2" />
</wd:MultiSelectComboBox>
<!-- Step wizard -->
<wd:Step StepIndex="1">
<wd:StepItem Content="Step 1" />
<wd:StepItem Content="Step 2" />
<wd:StepItem Content="Step 3" />
</wd:Step>
<!-- Carousel -->
<wd:Carousel ItemsSource="{Binding CarouselItems}" />
<!-- Radar chart -->
<wd:ChartRadar Datas="{Binding RadarDatas}" />
<!-- Bar chart -->
<wd:ChartBar Datas="{Binding BarDatas}" />
<!-- Line chart -->
<wd:ChartLine Datas="{Binding LineDatas}" />
<!-- Pie chart (LiveCharts-style) -->
<wd:ChartPie Datas="{Binding PieDatas}" />
<!-- Dashboard gauge (NuGet version) -->
<wd:Gauge Value="75" MaxValue="100" />
<!-- Circular progress bar -->
<wd:CircleProgressBar Value="75" /><!-- Badge notification -->
<Button wd:Badge.IsShow="True" wd:Badge.Text="new" Content="Messages" />
<!-- Button loading state -->
<Button wd:Loading.IsShow="True" wd:Loading.LoadingType="Normal" Content="Submit" />
<!-- TextBox watermark + clear button -->
<TextBox wd:ElementHelper.Watermark="Enter username" wd:ElementHelper.IsClear="True" />
<!-- PasswordBox monitoring -->
<PasswordBox wd:PasswordBoxHelper.IsMonitoring="True" wd:ElementHelper.Watermark="Password" />
<!-- DatePicker with time -->
<DatePicker wd:DatePickerHelper.ShowTime="True" />
<!-- Panel spacing -->
<WrapPanel wd:PanelHelper.Spacing="10">
<Button Content="Button 1" />
<Button Content="Button 2" />
</WrapPanel>
<!-- Corner radius -->
<Button wd:ElementHelper.CornerRadius="5" Content="Rounded" />
<TextBox wd:ElementHelper.CornerRadius="3" />
<DataGrid wd:ElementHelper.CornerRadius="3" />
<!-- Striped progress bar -->
<ProgressBar wd:ElementHelper.IsStripe="True" Value="80" />
<!-- Closable TabItem -->
<TabItem wd:ElementHelper.IsClear="True" Header="Closable Tab" />
<!-- TreeView scroll animation -->
<TreeView wd:TreeViewHelper.IsScrollAnimation="true" />Set ScrollViewerBehavior.IsBackToTopEnabled and/or ScrollViewerBehavior.IsBackToBottomEnabled to True on a scrollable control. The corresponding button appears at the bottom-right while the pointer or keyboard focus is within the control, and hides when the content reaches its destination.
<ListBox
wd:ScrollViewerBehavior.IsBackToTopEnabled="True"
ItemsSource="{Binding Items}" />
<ListView
wd:ScrollViewerBehavior.IsBackToTopEnabled="True"
ItemsSource="{Binding Items}" />
<DataGrid
wd:ScrollViewerBehavior.IsBackToTopEnabled="True"
wd:ScrollViewerBehavior.IsBackToBottomEnabled="True"
ItemsSource="{Binding Items}" />
<ScrollViewer
wd:ScrollViewerBehavior.IsBackToTopEnabled="True"
wd:ScrollViewerBehavior.IsBackToBottomEnabled="True">
<!-- long content -->
</ScrollViewer>The behavior can also be set directly on ScrollViewer, WDScrollViewer, or TreeView. For a Panel, set it on the containing ScrollViewer because panels do not provide scrolling themselves. It does not replace the ItemsPanel, so list virtualization is preserved.
Open the Attached Properties menu in the sample application to see an interactive example.
<!-- Normal button -->
<Button Style="{StaticResource WD.NormalButton}" Content="Normal" />
<!-- Primary buttons (various themes) -->
<Button Style="{StaticResource WD.PrimaryButton}" Content="Primary" />
<Button Style="{StaticResource WD.SuccessPrimaryButton}" Content="Success" />
<Button Style="{StaticResource WD.WarningPrimaryButton}" Content="Warning" />
<Button Style="{StaticResource WD.DangerPrimaryButton}" Content="Danger" />
<!-- Default buttons (various themes) -->
<Button Style="{StaticResource WD.SuccessDefaultButton}" Content="Success" />
<Button Style="{StaticResource WD.WarningDefaultButton}" Content="Warning" />
<Button Style="{StaticResource WD.DangerDefaultButton}" Content="Danger" />WD provides a set of theme resources you can reference in XAML:
| Resource Key | Type | Description |
|---|---|---|
WD.PrimaryBrush |
SolidColorBrush | Primary color |
WD.SuccessBrush |
SolidColorBrush | Success color |
WD.WarningBrush |
SolidColorBrush | Warning color |
WD.DangerBrush |
SolidColorBrush | Danger color |
WD.InfoSolidColorBrush |
SolidColorBrush | Info color |
WD.LightBrush |
SolidColorBrush | Light color |
WD.CircularSingularSolidColorBrush |
SolidColorBrush | Circular accent color |
WD.BackgroundBrush |
SolidColorBrush | Background color |
WD.PrimaryTextBrush |
SolidColorBrush | Primary text color |
WD.WarningGeometry |
Geometry | Warning icon |
Important: Implementations marked π‘ Sample-only live in the sample project's
Controls/orExampleViews/folders and are not shipped as built-in WD controls in the NuGet package. They may compose native WPF controls with WD styles, controls, or helpers.
The sample navigation identifies these implementations and composed effects with a blue-gray DEMO badge. Hover for an explanation; the tooltip follows the selected language. NEW and UPDATE remain independent change-status badges and can appear alongside DEMO; for example, ActivityFeed can show both DEMO and UPDATE. Ordinary usage samples for built-in WD controls and helpers do not receive DEMO.
| Control | Source | Example File | Description |
|---|---|---|---|
wd:Window |
NuGet | MainWindow.xaml | Custom window (ToolWindow / NoneTitleBar / Normal / HighTitleBar) |
wd:NotifyIcon |
NuGet | NotifyIconExample.xaml | System tray icon |
wd:DrawerMenu |
NuGet | DrawerMenuExample.xaml | Win10-style drawer navigation |
wd:NavMenu3D |
NuGet | NavMenu3DExample.xaml | 3D animated navigation menu |
wd:NavScrollPanel |
NuGet | NavScrollPanelExample.xaml | Win10 settings-style nav panel |
| π‘ TransitionPanel | Sample-only | TransitionPanelExample.xaml | Transition animation panel |
wd:Drawer |
NuGet | DrawerExample.xaml | Slide-out panel (Top/Bottom/Left/Right) |
wd:Mask |
NuGet | MaskExample.xaml | Modal overlay |
wd:AcrylicBlur |
NuGet | AcrylicBlurExample.xaml | Acrylic blur window |
| π‘ TaskbarItemInfo | Sample-only | TaskbarItemInfoExample.xaml | Taskbar badge |
| Control | Example File | Description |
|---|---|---|
Theme |
ThemeExample.xaml | Theme switching (Light/Dark/Languages) |
Window |
WindowBasicExample.xaml | Basic windows (ToolWindow/NoneTitleBar) |
Loading |
LoadingBasicExample.xaml | Loading states (button loading/loading task) |
Button |
ButtonExample.xaml | Button styles |
TextBox |
TextBoxExample.xaml | TextBox (watermark / clear button / corner radius) |
PasswordBox |
PasswordBoxExample.xaml | PasswordBox (watermark / clear / monitor / plain text toggle) |
ComboBox |
ComboBoxExample.xaml | ComboBox (watermark / editable / corner radius) |
CheckBox |
CheckboxExample.xaml | Checkbox |
RadioButton |
RadioButtonExample.xaml | Radio button |
ToggleButton |
ToggleButtonExample.xaml | Toggle button |
DatePicker |
DatePickerExample.xaml | Date picker (with time selection) |
DateTimePicker |
DateTimePickerExample.xaml | DateTime picker |
Slider |
SliderExample.xaml | Slider (horizontal / vertical) |
ProgressBar |
ProgressBarExample.xaml | Progress bar (striped / indeterminate / vertical) |
DataGrid |
DataGridExample.xaml | Data grid (row header selection / template columns / grid lines) |
ListBox |
ListBoxExample.xaml | List box |
ListView |
ListViewExample.xaml | List view (GridView) |
TreeView |
TreeViewExample.xaml | Tree view (scroll animation) |
Expander |
ExpanderExample.xaml | Expander (4 directions) |
GroupBox |
GroupBoxExample.xaml | Group box |
TabControl |
TabControlExample.xaml | Tab control (4 directions / closable) |
Menu |
MenuExample.xaml | Menu bar |
wd:SplitButton |
NuGet | SplitButtonExample.xaml |
Calendar |
CalendarExample.xaml | Calendar |
wd:Segmented |
NuGet | SegmentedExample.xaml |
| Control | Source | Example File | Description |
|---|---|---|---|
wd:ColorPicker |
NuGet | ColorPickerExample.xaml | Color picker |
wd:TimePicker |
NuGet | TimePickerExample.xaml | Time picker |
wd:DateRangePicker |
NuGet | DateRangePickerExample.xaml | Date range picker |
wd:NumericBox |
NuGet | NumericBoxExample.xaml | Numeric input |
wd:IPEditBox |
NuGet | IPEditBoxExample.xaml | IP address input |
wd:MultiSelectComboBox |
NuGet | MultiSelectComboBoxExample.xaml | Multi-select combo box |
| π‘ MultiSelectSearchComboBox | Sample-only | MultiSelectSearchComboBoxExample.xaml | Searchable multi-select combo box |
| π‘ Password | Sample-only | PasswordExample.xaml | Composed password show/hide sample |
wd:VerifyCode |
NuGet | VerifyCodeExample.xaml | CAPTCHA drawing |
| π‘ RoundPicker | Sample-only | RoundPickerExample.xaml | Circular color picker |
wd:RulerControl |
NuGet | RulerExample.xaml | Ruler control |
wd:ScrollIntoView |
NuGet | SelectorExample.xaml | List positioning helper |
wd:Dial |
NuGet | DialExample.xaml | Dial pad |
wd:GestureUnlock |
NuGet | GestureUnlockExample.xaml | Gesture pattern unlock |
wd:SvgViewer |
NuGet | SvgViewerExample.xaml | SVG viewer |
wd:OtpBox |
NuGet | OtpBoxExample.xaml | OTP verification code input (auto-jump / backspace / paste) |
| Control | Source | Example File | Description |
|---|---|---|---|
wd:RingLoading |
NuGet | RingLoadingExample.xaml | Ring loading animation |
wd:BallLoading |
NuGet | BallLoadingExample.xaml | Bouncing ball animation |
| π‘ StreamerLoading | Sample-only | StreamerLoadingExample.xaml | Streamer animation |
wd:WaitLoading |
NuGet | WaitLoadingExample.xaml | Wait animation |
wd:CycleLoading |
NuGet | CycleLoadingExample.xaml | Cycle animation |
wd:RollLoading |
NuGet | RollLoadingExample.xaml | Rolling animation |
wd:Loading (attached) |
NuGet | LoadingExample.xaml | Button/control loading state |
| Control | Source | Example File | Description |
|---|---|---|---|
wd:ChartRadar |
NuGet | ChartRadarExample.xaml | Radar chart |
wd:ChartBar |
NuGet | ChartBarExample.xaml | Bar chart |
wd:ChartLine |
NuGet | ChartLineExample.xaml | Line chart |
wd:ChartPie |
NuGet | ChartPieExample.xaml | Pie chart |
| π‘ Dashboard | Sample-only | DashboardExample.xaml | Dashboard gauge (tick marks follow progress) |
| π‘ PieSegment | Sample-only | PieSegmentExample.xaml | Segmented pie chart sample (distinct from wd:ChartPie) |
wd:Gauge |
NuGet | GaugeExample.xaml | Gauge control |
| π‘ LineChart | Sample-only | LineChartExample.xaml | Line chart (alternate implementation) |
wd:CircleProgressBar |
NuGet | CircleProgressBarExample.xaml | Circular progress bar |
wd:Step |
NuGet | StepExample.xaml | Step wizard |
wd:BreadCrumbBar |
NuGet | BreadCrumbBarExample.xaml | Breadcrumb navigation |
wd:Pagination |
NuGet | PaginationExample.xaml | Pagination control |
| π‘ ActivityFeed | Sample-only | ActivityFeedExample.xaml | Activity feed (Gitee-style) |
wd:Thermometer |
NuGet | ThermometerExample.xaml | Thermometer |
wd:DataGridFilter |
NuGet | DataGridFilterExample.xaml | DataGrid column filter engine |
| Control | Source | Example File | Description |
|---|---|---|---|
wd:Carousel |
NuGet | CarouselExample.xaml | Carousel (auto-play / dot indicators / arrows / click navigation) |
wd:FocusCarousel |
NuGet | FocusCarouselExample.xaml | Emphasizer carousel (3D flip + zoom effect) |
wd:CardCarousel |
NuGet | CardCarouselExample.xaml | Master carousel (multi-layer overlay animation) |
wd:CircleMenu |
NuGet | CircleMenuExample.xaml | Circular menu |
wd:SixGridView |
NuGet | SixGirdViewExample.xaml | Six-column grid layout |
wd:WaterfallPanel |
NuGet | WaterfallPanelExample.xaml | Waterfall / masonry panel |
wd:WaterfallItemsControl |
NuGet | WaterfallPanelExample.xaml | Masonry items control with a scrolling template |
wd:VirtualizingWrapPanel |
NuGet | VirtualizingWrapPanelExample.xaml | Virtualizing WrapPanel |
| π‘ TransformLayout | Sample-only | TransformLayoutExample.xaml | Draggable, resizable, rotatable control |
wd:DrapView |
NuGet | DrapViewExample.xaml | Drag-and-drop view |
wd:Spacing (attached) |
NuGet | SpacingExample.xaml | Panel child spacing |
wd:PanningItems |
NuGet | PanningItemsExample.xaml | Panning control (touch swipe) |
wd:WDScrollViewer / wd:ScrollViewerBehavior |
NuGet | ScrollViewerAnimationExample.xaml | Animated scrolling and back-to-top helper |
wd:IconicThumbnail |
NuGet | IconicThumbnailExample.xaml | Iconic thumbnail |
Scrolling reuses cached item positions and uses per-column binary searches to select nearby items.
Positions are rebuilt when width, data, or measured realized-item heights change.
WDScrollViewer retains smooth scrolling: consecutive wheel input accumulates its target,
while direction changes restart from the current offset. Animations last 250ms without a fixed
40 FPS cap. Actual smoothness depends on item templates and hardware.
These changes use APIs available in .NET Framework 4.0. Windows 7 requires a compatible
.NET Framework build; this does not imply Windows 7 support for modern .NET targets.
For data binding, use WaterfallItemsControl without an outer ScrollViewer:
<wd:WaterfallItemsControl MinColumnWidth="200" Spacing="16" ItemsSource="{Binding Items}">
<wd:WaterfallItemsControl.ItemTemplate>
<DataTemplate>
<Image Source="{Binding ImageUri}" Stretch="Uniform" />
</DataTemplate>
</wd:WaterfallItemsControl.ItemTemplate>
</wd:WaterfallItemsControl>It inherits ItemsSource, ItemTemplate, and ItemTemplateSelector, enables recycling by default,
and exposes Columns, MinColumnWidth, Spacing, and EstimatedItemHeight.
Use ScrollViewer.VerticalScrollBarVisibility to control the scrollbar.
A finite host height is still required for virtualization. Use WaterfallPanel for direct XAML
children or custom hosts.
Columns defaults to 3. MinColumnWidth defaults to 0 (fixed columns).
A positive MinColumnWidth selects max(1, floor((availableWidth + Spacing) / (MinColumnWidth + Spacing)))
columns. A narrow container still has one column, which may be narrower than the minimum.
ActualColumns reports the selected count. With infinite available width, Columns is used,
and the widest natural item width (at least MinColumnWidth) determines the column width.
The same panel supports direct XAML children and ItemsControl.ItemsSource.
For UI virtualization, give the host a finite viewport and use an ItemsControl template containing
ScrollViewer CanContentScroll="True" with an ItemsPresenter as its content.
Set VirtualizingStackPanel.IsVirtualizing="True" and VirtualizingStackPanel.VirtualizationMode="Recycling"
on the ItemsControl, and use WaterfallPanel as its ItemsPanel.
Do not wrap this host in a vertical StackPanel or an outer scroller providing infinite height.
Without a finite scrolling viewport the panel generates all containers; setting IsVirtualizing="False"
also generates all containers.
Unmeasured items use EstimatedItemHeight (default 200). Actual measurements update positions and
the scroll extent, so distant jumps and asynchronously loaded images may cause layout shifts.
Reserve a suitable initial height for asynchronous content.
This is UI, not data, virtualization: metadata storage is O(item count), and layout calculation is
O(item count Γ columns). The example includes XAML, MVVM, and a 5000-card virtualization tab.
| Control | Source | Example File | Description |
|---|---|---|---|
wd:BreatheLight |
NuGet | BreatheLightExample.xaml | Breathing light animation |
wd:SpotLight |
NuGet | SpotLightExample.xaml | Spotlight effect |
wd:EdgeLight |
NuGet | EdgeLightExample.xaml | Edge marquee light |
| π‘ RainbowButtons | Sample-only | RainbowButtonsExample.xaml | Rainbow buttons |
wd:Shake |
NuGet | ShakeExample.xaml | Window shake |
| π‘ BubbleSelection | Sample-only | BubbleSelectionExample.xaml | Bubble selection sample |
wd:StarrySky |
NuGet | StarrySkyExample.xaml | Starry sky animation |
| π‘ SnowCanvas | Sample-only | SnowCanvasExample.xaml | Christmas tree & snow canvas |
| π‘ SpeedRockets | Sample-only | SpeedRocketsExample.xaml | Speed rocket animation |
| π‘ CountdownTimer | Sample-only | CountdownTimerExample.xaml | Countdown timer animation |
| π‘ NumberCard | Sample-only | NumberCardExample.xaml | 3D flip countdown cards |
wd:AnimationGrid |
NuGet | AnimationGridExample.xaml | Animation grid |
| π‘ LogoAnimation | Sample-only | LogoAnimationExample.xaml | Login logo animation |
| π‘ SongWords | Sample-only | SongWordsExample.xaml | Lyrics scroll animation |
wd:AnimationAudio |
NuGet | AnimationAudioExample.xaml | Audio waveform visualization |
| π‘ Barrage | Sample-only | BarrageExample.xaml | Danmaku / barrage control |
| π‘ CanvasHandWriting | Sample-only | CanvasHandWritingExample.xaml | Smooth canvas handwriting |
| π‘ Drawing | Sample-only | DrawingExample.xaml | Freehand drawing |
| π‘ DrawPrize | Sample-only | DrawPrizeExample.xaml | Lottery wheel |
| Control | Source | Example File | Description |
|---|---|---|---|
wd:GrayscaleEffect |
NuGet | GrayscaleEffectExample.xaml | Grayscale filter effect (adjustable intensity) |
| Control | Source | Example File | Description |
|---|---|---|---|
wd:ScreenCut |
NuGet | ScreenCutExample.xaml | Screen capture (pen / arrow annotation) |
wd:CropImage |
NuGet | CropImageExample.xaml | Image cropping |
wd:CropAvatar |
NuGet | CropAvatarExample.xaml | Avatar cropping selector |
| π‘ ImageCrop | Sample-only | ImageCropExample.xaml | Image nine-grid tiling effect sample |
| π‘ CutImage | Sample-only | CutImageExample.xaml | User avatar cropping solution |
wd:Magnifier |
NuGet | MagnifierExample.xaml | Magnifier |
| Control | Source | Example File | Description |
|---|---|---|---|
wd:Badge (attached) |
NuGet | BadgeExample.xaml | Badge notification |
wd:Toast |
NuGet | ToastExample.xaml | Toast message popup |
wd:Tag |
NuGet | TagExample.xaml | Tag control |
wd:PathIcon |
NuGet | PathIconExample.xaml | Vector path icon |
wd:AllPathIcon |
NuGet | AllPathIconExample.xaml | Built-in icon browser |
MessageBox (static class) |
NuGet | MessageBoxExample.xaml | Message dialog |
| Control | Source | Example File | Description |
|---|---|---|---|
| π‘ ZooSemy | Sample-only | ZooSemyExample.xaml | Skeuomorphic rotary knob (volume) |
| π‘ Flame | Sample-only | FlameExample.xaml | Flame animation |
| π‘ Desktop | Sample-only | DesktopBackground.xaml | Dynamic desktop wallpaper |
| π‘ AMap | Sample-only | BingAMapExample.xaml | Map integration (Bing / AutoNavi) |
| π‘ LoginWindow | Sample-only | LoginExample.xaml | Login window template |
| π‘ ChatEmoji | Sample-only | ChatEmojiExample.xaml | Emoji + text chat |
MessageBox is a static message dialog class provided by WPFDevelopers, designed as a drop-in replacement for System.Windows.MessageBox with a more polished and customizable appearance.
Note:
MessageBoxis a static class, not a XAML control. It can only be called from C# code.
To avoid conflicts with System.Windows.MessageBox, use an alias:
using MessageBox = WPFDevelopers.Controls.MessageBox;MessageBox.Show() provides 5 overloads:
// 1. Message text only (default OK button, no icon)
MessageBoxResult Show(string messageBoxText, Window owner = null, bool isDefault = true)
// 2. Message text + caption
MessageBoxResult Show(string messageBoxText, string caption, Window owner = null, bool isDefault = true)
// 3. Message text + caption + buttons
MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, Window owner = null, bool isDefault = true)
// 4. Message text + caption + icon
MessageBoxResult Show(string messageBoxText, string caption, MessageBoxImage icon, Window owner = null, bool isDefault = true)
// 5. Message text + caption + buttons + icon (full signature)
MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, Window owner = null, bool isDefault = true)| Parameter | Type | Default | Description |
|---|---|---|---|
messageBoxText |
string | β | Message content |
caption |
string | β | Dialog title |
button |
MessageBoxButton | OK | Button set: OK / OKCancel / YesNo / YesNoCancel |
icon |
MessageBoxImage | None | Icon type: Information / Warning / Error / Question |
owner |
Window | null | Parent window. When provided, the dialog centers on the owner with an overlay mask |
isDefault |
bool | true | Whether the first button is the default button (triggered by Enter key) |
| MessageBoxImage | Icon | Color |
|---|---|---|
Information |
Info icon | Success (green) |
Warning |
Warning icon | Warning (orange) |
Error |
Error icon | Danger (red) |
Question |
Question icon | Primary (blue) |
// File deleted successfully
MessageBox.Show("File deleted successfully.", "Message", MessageBoxButton.OK, MessageBoxImage.Information);// Uses default OK button
MessageBox.Show("Performing this action may cause the file to become inaccessible!", "Warning", MessageBoxImage.Warning);MessageBox.Show("The file does not exist.", "Error", MessageBoxImage.Error);var result = MessageBox.Show("The file does not exist. Continue?", "Confirm", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
switch (result)
{
case MessageBoxResult.Yes:
// User clicked "Yes"
break;
case MessageBoxResult.No:
// User clicked "No"
break;
case MessageBoxResult.Cancel:
// User clicked "Cancel" or closed the dialog
break;
}// When owner is passed, the dialog centers on the parent window and shows an overlay mask
MessageBox.Show("Operation successful!", "Info", MessageBoxButton.OK, MessageBoxImage.Information, owner: this);- Close methods: Click the close button (top-right), press
Escape, or click any button - Owner window: When
owneris provided, the dialog centers on the parent window and displays a mask overlay. Without an owner, it auto-detects the current window or centers on screen - Button text: Automatically localized via
LanguageManager(follows system language)
SplitButton is a split button control provided by WPFDevelopers. The left side is a clickable main button area, and the right side is a dropdown toggle button. It supports both text options and rich content options with icons.
<wd:SplitButton
Width="150"
Content="File"
ItemsSource="{Binding MenuItems}"
SelectionChanged="SplitButton_SelectionChanged" />// ViewModel or Code-behind
public ObservableCollection<string> MenuItems { get; } = new ObservableCollection<string>
{
"Save in PDF",
"Save in Word",
"Save in Excel",
"Save in Image"
};
private void SplitButton_SelectionChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
// e.NewValue is the selected item
}<wd:SplitButton Width="120" Content="File" ItemsSource="{Binding MenuItems}" />
<wd:SplitButton Width="120" Content="File" ItemsSource="{Binding MenuItems}"
Style="{StaticResource WD.SplitButtonSuccess}" />
<wd:SplitButton Width="120" Content="File" ItemsSource="{Binding MenuItems}"
Style="{StaticResource WD.SplitButtonWarning}" />
<wd:SplitButton Width="120" Content="File" ItemsSource="{Binding MenuItems}"
Style="{StaticResource WD.SplitButtonDanger}" /><wd:SplitButton Width="120" Content="File" ItemsSource="{Binding MenuItems}"
Style="{StaticResource WD.SplitButtonPrimary}" />
<wd:SplitButton Width="120" Content="File" ItemsSource="{Binding MenuItems}"
Style="{StaticResource WD.SplitButtonSuccessPrimary}" />
<wd:SplitButton Width="120" Content="File" ItemsSource="{Binding MenuItems}"
Style="{StaticResource WD.SplitButtonWarningPrimary}" />
<wd:SplitButton Width="120" Content="File" ItemsSource="{Binding MenuItems}"
Style="{StaticResource WD.SplitButtonDangerPrimary}" /><wd:SplitButton
Width="150"
Content="File"
ItemsSource="{Binding MenuItems}"
Style="{StaticResource WD.SplitButtonSuccess}">
<MenuItem Header="Copy">
<MenuItem.Icon>
<wd:PathIcon Kind="Copy" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Paste" />
<MenuItem Header="Cut" />
</wd:SplitButton>| Property | Type | Default | Description |
|---|---|---|---|
Content |
object | null | Main button display content |
ItemsSource |
object | null | Dropdown menu data source (IEnumerable) |
IsDropDownOpen |
bool | false | Whether dropdown is open (two-way binding) |
ContextMenuStyle |
Style | null | Custom ContextMenu style |
| Event | Description |
|---|---|
Click |
Fired when the main button area is clicked (clicking ToggleButton does NOT fire this) |
SelectionChanged |
Fired when a dropdown menu item is selected |
| Style Key | Description |
|---|---|
WD.SplitButton (default) |
Border + transparent background, border turns primary color on hover |
WD.SplitButtonDefault |
Border + background, full hover/pressed/focused feedback with primary color |
WD.SplitButtonPrimary |
No border + solid primary color background + white text, opacity 0.9 on hover |
WD.SplitButtonSuccess |
Border + background, full hover/pressed/focused feedback with success color |
WD.SplitButtonSuccessPrimary |
No border + solid success background + white text |
WD.SplitButtonWarning |
Border + background, full hover/pressed/focused feedback with warning color |
WD.SplitButtonWarningPrimary |
No border + solid warning background + white text |
WD.SplitButtonDanger |
Border + background, full hover/pressed/focused feedback with danger color |
WD.SplitButtonDangerPrimary |
No border + solid danger background + white text |
| Action | Behavior |
|---|---|
| Click main button area | Fires Click event |
| Click ToggleButton | Expands/collapses dropdown menu |
| Click menu item | Button Content updates to selected item, fires SelectionChanged |
| Click outside menu | Automatically closes dropdown |
Carousel is a carousel control provided by WPFDevelopers, supporting auto-play, dot indicators, arrow navigation, click navigation, and more.
<wd:Carousel
Width="400" Height="200"
AutoPlay="True"
AutoPlayInterval="0:0:4"
ShowArrows="True"
ItemClick="Carousel_ItemClick">
<Border Background="#722ed1">
<TextBlock Text="Slide 1" Foreground="White" FontSize="24" />
</Border>
<Border Background="#eb2f96">
<TextBlock Text="Slide 2" Foreground="White" FontSize="24" />
</Border>
<Border Background="#1890ff">
<TextBlock Text="Slide 3" Foreground="White" FontSize="24" />
</Border>
</wd:Carousel><wd:Carousel
ItemsSource="{Binding ImagePaths}"
DisplayMemberPath="URL"
AutoPlay="True"
ItemClickCommand="{Binding CarouselClickCommand}" />// Data model
public class CarouselSlideModel
{
public string Title { get; set; }
public string URL { get; set; }
}
// ViewModel
public ObservableCollection<CarouselSlideModel> ImagePaths { get; set; }
public ICommand CarouselClickCommand => new RelayCommand(param =>
{
if (param is CarouselSlideModel model)
{
Toast.Push($"Clicked image - {model.Title}", ToastImage.Success, true);
}
});| Property | Type | Default | Description |
|---|---|---|---|
ItemsSource |
IEnumerable | null | Data source |
SelectedIndex |
int | 0 | Current selected item index |
SelectedItem |
object | null | Current selected item |
AutoPlay |
bool | false | Enable auto-play |
AutoPlayInterval |
TimeSpan | 3 seconds | Auto-play interval |
AnimationDuration |
double | 0.5 | Transition animation duration (seconds) |
ShowDots |
bool | true | Show dot indicators |
ShowArrows |
bool | true | Show left/right arrows |
ItemTemplate |
DataTemplate | null | Data template |
DisplayMemberPath |
string | null | Display member path (shows property value directly) |
| Event | Description |
|---|---|
ItemClick |
Fired when a slide is clicked |
SelectedItemChanged |
Fired when selected item changes |
| Method | Description |
|---|---|
GoToNext() |
Navigate to next slide |
GoToPrevious() |
Navigate to previous slide |
A carousel with 3D flip + zoom effects, where the center item is enlarged and highlighted:
<wd:FocusCarousel>
<Image Source="pack://application:,,,/Images/photo1.jpg" />
<Image Source="pack://application:,,,/Images/photo2.jpg" />
<Image Source="pack://application:,,,/Images/photo3.jpg" />
</wd:FocusCarousel>A carousel with multi-layer overlay animation and auto-play/interval control:
<wd:CardCarousel AutoPlay="True" AutoPlayInterval="0:0:5">
<Image Source="pack://application:,,,/Images/photo1.jpg" />
<Image Source="pack://application:,,,/Images/photo2.jpg" />
<Image Source="pack://application:,,,/Images/photo3.jpg" />
</wd:CardCarousel>| Property | Type | Default | Description |
|---|---|---|---|
AutoPlay |
bool | false | Enable auto-play |
AutoPlayInterval |
TimeSpan | 0:0:3 | Playback interval (TimeSpan) |
GrayscaleEffect is a pixel shader effect that converts any visual element to grayscale display, commonly used for global grayscale mode (e.g., memorial days).
<Image Source="photo.jpg">
<Image.Effect>
<wd:GrayscaleEffect Factor="1" />
</Image.Effect>
</Image><wd:Window>
<wd:Window.Effect>
<wd:GrayscaleEffect x:Name="grayscaleEffect" Factor="0" />
</wd:Window.Effect>
</wd:Window>// Enable grayscale
var animation = new DoubleAnimation
{
To = 1,
Duration = TimeSpan.FromMilliseconds(1000),
EasingFunction = new SineEase { EasingMode = EasingMode.EaseOut }
};
grayscaleEffect.BeginAnimation(GrayscaleEffect.FactorProperty, animation);
// Disable grayscale
animation.To = 0;
grayscaleEffect.BeginAnimation(GrayscaleEffect.FactorProperty, animation);| Property | Type | Default | Description |
|---|---|---|---|
Factor |
double | 0 | Grayscale intensity, 0 = original color, 1 = full grayscale |
Brightness |
double | 0 | Brightness adjustment |
OtpBox is a control designed for OTP (One-Time Password) input scenarios, supporting auto-focus jump, backspace retreat, paste fill, and more.
<wd:OtpBox Length="6" Completed="OtpBoxCompleted" /><wd:OtpBox
Length="6"
Value="{Binding OtpCode, Mode=TwoWay}"
CompletedCommand="{Binding VerifyCommand}" />// Event approach
private void OtpBoxCompleted(object sender, RoutedEventArgs e)
{
var otpBox = e.OriginalSource as OtpBox;
var pwd = otpBox?.Value ?? string.Empty;
if (pwd != _otpPassword)
{
myOtpBox.State = ControlState.Error;
return;
}
myOtpBox.State = ControlState.Success;
}
// Command approach
public ICommand CompletedCommand => new RelayCommand(param =>
{
var pwd = param.ToString();
// Validation logic...
});| Property | Type | Default | Description |
|---|---|---|---|
Length |
int | 4 | Number of OTP digits |
Value |
string | "" | Current value (supports two-way binding) |
State |
ControlState | None | Validation state (None/Success/Error) |
CompletedCommand |
ICommand | null | Command executed on completion |
| Event | Description |
|---|---|
Completed |
Fired when all digits are filled |
| Action | Behavior |
|---|---|
| Enter a digit | Auto-jump to next input box |
| Backspace (empty box) | Jump to previous box and delete last character |
| Ctrl+V Paste | Auto-fill digit by digit, filter non-numeric characters |
| Arrow keys β β | Switch between input boxes |
| Enter / Tab | Jump to next input box |
| Error state | Auto-clear and refocus after 1.5 seconds |
| Success state | Auto-reset to default state after 1.5 seconds |
If you prefer not to configure from scratch, reference the sample project in this repository:
src/WPFDevelopers.Samples.Shared/
βββ App.xaml # App entry point & theme config
βββ ExampleViews/ # Full control example pages
β βββ MainWindow.xaml # Main window (left menu + right content)
β βββ UsageGuide.xaml # Usage guide page
β βββ UsageColor.xaml # Color usage guide
β βββ Basics/ # Basic control examples (23 individual pages)
β β βββ ThemeExample.xaml
β β βββ MenuExample.xaml
β β βββ WindowBasicExample.xaml
β β βββ LoadingBasicExample.xaml
β β βββ ButtonExample.xaml
β β βββ RadioButtonExample.xaml
β β βββ CheckboxExample.xaml
β β βββ TextBoxExample.xaml
β β βββ PasswordBoxExample.xaml
β β βββ ComboBoxExample.xaml
β β βββ ToggleButtonExample.xaml
β β βββ DatePickerExample.xaml
β β βββ DateTimePickerExample.xaml
β β βββ CalendarExample.xaml
β β βββ SliderExample.xaml
β β βββ ProgressBarExample.xaml
β β βββ DataGridExample.xaml
β β βββ ListBoxExample.xaml
β β βββ ListViewExample.xaml
β β βββ TreeViewExample.xaml
β β βββ ExpanderExample.xaml
β β βββ GroupBoxExample.xaml
β β βββ TabControlExample.xaml
β βββ Loading/ # Loading animation series
β β βββ BallLoadingExample.xaml
β β βββ RingLoadingExample.xaml
β β βββ StreamerLoadingExample.xaml
β β βββ WaitLoadingExample.xaml
β β βββ CycleLoadingExample.xaml
β β βββ RollLoadingExample.xaml
β βββ DrawerMenu/ # Drawer menu sub-pages
β β βββ HomePage.xaml
β β βββ EmailPage.xaml
β β βββ EdgePage.xaml
β βββ NavScrollPanel/ # Nav settings panel sub-pages
β β βββ About.xaml
β β βββ PrivacySettings.xaml
β β βββ PlaybackSettings.xaml
β β βββ ShortcutKeys.xaml
β β βββ DesktopLyrics.xaml
β βββ LoginWindow/ # Login window template
β β βββ CustomControl/
β β βββ CustomStyle/
β β βββ LoginExample.xaml
β βββ CropAvatar/ # Avatar cropping
β β βββ CropAvatarExample.xaml
β β βββ CropAvatarWindow.xaml
β βββ NumberCard/ # Countdown cards
β β βββ NumberCardExample.xaml
β β βββ NumberCardControl.xaml
β βββ SpeedRockets/ # Rocket animation
β β βββ SpeedRocketsExample.xaml
β β βββ SpeedRocketsMini.xaml
β βββ ZooSemy/ # Skeuomorphic knob
β β βββ ZooSemyExample.xaml
β β βββ VolumeControl.xaml
β βββ CanvasHandWriting/ # Handwriting
β β βββ CanvasHandWritingExample.xaml
β βββ Desktop/ # Desktop wallpaper
β β βββ DesktopBackground.xaml
β β βββ DesktopPlayVideo.xaml
β βββ Passwrod/ # Password controls
β β βββ PasswordExample.xaml
β β βββ PasswordWithPlainText.xaml
β βββ Map/ # Map
β β βββ MapViewExample.xaml
β β βββ MapViewExample.xaml.cs
β β βββ MapViewFeaturesWindow.xaml
β β βββ MapViewFeaturesWindow.xaml.cs
β β βββ TiandituTileSource.cs
β β βββ AMapTileSource.cs
β βββ DrapView/ # Drag view
β β βββ DrapViewExample.xaml
β βββ ... (more example files)
βββ Controls/ # Sample helper controls (CodeViewer, NavigateMenu, etc.)
βββ ViewModels/ # Sample ViewModels
βββ Models/ # Data models
βββ Helpers/MenuEnum.cs # All example category enum
βββ Converts/ # Value converters
Each example page includes a built-in code viewer (CodeViewer) that lets you inspect the corresponding XAML/C# source code directly.