WPF does not provide a built-in NumericUpDown control like WinForms. While third-party libraries exist, many projects require zero external dependencies for reasons such as licensing, application size, or long-term maintenance.
This post presents the best native WPF solution: building a reusable NumericUpDown UserControl using only standard WPF features. The result is a clean, MVVM-friendly control that supports numeric input with increment and decrement buttons.
Building a Native NumericUpDown Control in WPF (Without Third-Party Libraries)
Getting Started
Windows Presentation Foundation (WPF) does not include a built-in NumericUpDown control, which often leads developers to rely on third-party libraries or workarounds when numeric input with increment and decrement functionality is required. In projects where external dependencies are undesirable—due to licensing concerns, long-term maintenance, or the need to keep the application lightweight—a native solution becomes especially valuable.
Why Use a Custom UserControl?
Using a UserControl is the most practical approach when:- You want fast development
- You need reuse across multiple views
- You want dependency properties for binding
- You do not require full theme-level customization
Features of the Custom NumericUpDown
- Integer value input
- Up and Down buttons
- Minimum and Maximum constraints
- Two-way data binding
- No third-party libraries
- Easy to extend
Steps to Create NumericUpDown in WPF
This section introduces a step-by-step approach to building a custom NumericUpDown control using native WPF components, allowing you to achieve full control over behavior, appearance, and data binding without relying on third-party libraries. By following these steps, you can create a lightweight, MVVM-friendly solution that integrates seamlessly into any WPF application.
Create the UserControl Layout
The first step in building a custom NumericUpDown control in WPF is to create a UserControl. A UserControl allows you to combine multiple existing WPF controls (such as a TextBox and Button) into a single reusable component. This approach is ideal for a NumericUpDown control because it keeps the implementation simple, readable, and easy to reuse across different windows or views. Create a usercontrol like below code and name it NumericUpDown.
NumericUpDown.xaml<UserControl x:Class="YourApp.Controls.NumericUpDown"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="25" Width="120">
<Border BorderBrush="Gray" BorderThickness="1" CornerRadius="2">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<TextBox Text="{Binding Value,
RelativeSource={RelativeSource AncestorType=UserControl},
UpdateSourceTrigger=PropertyChanged}"
VerticalContentAlignment="Center"
Padding="4"/>
<StackPanel Grid.Column="1">
<Button Content="▲" Padding="0" Click="Up_Click"/>
<Button Content="▼" Padding="0" Click="Down_Click"/>
</StackPanel>
</Grid>
</Border>
</UserControl>
Layout Explanation
- TextBox displays and edits the numeric value
- StackPanel contains increment and decrement buttons
- RelativeSource binding allows the TextBox to bind directly to the UserControl’s
Valueproperty
By creating a UserControl, you encapsulate all numeric input functionality such as displaying the value, handling button clicks, and enforcing limits—inside a single component. This separation improves maintainability and makes the control easy to use in other parts of the application. Once created, the NumericUpDown UserControl can be dropped into any XAML view just like a standard WPF control, while still supporting data binding and customization through dependency properties.
Add Dependency Properties( Or Code-Behind)
In the NumericUpDown control, dependency properties allow the control to communicate seamlessly with the rest of the application. For example, the numeric value displayed in the control should be bindable to a ViewModel property, and constraints such as minimum and maximum values should be configurable directly from XAML. Open the NumericUpDown.xaml.cs file add below codes into it.
using System.Windows;
using System.Windows.Controls;
namespace YourApp.Controls
{
public partial class NumericUpDown : UserControl
{
public NumericUpDown()
{
InitializeComponent();
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register(
nameof(Value),
typeof(int),
typeof(NumericUpDown),
new FrameworkPropertyMetadata(
0,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public int Value
{
get => (int)GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
public static readonly DependencyProperty MinimumProperty =
DependencyProperty.Register(
nameof(Minimum),
typeof(int),
typeof(NumericUpDown),
new PropertyMetadata(0));
public int Minimum
{
get => (int)GetValue(MinimumProperty);
set => SetValue(MinimumProperty, value);
}
public static readonly DependencyProperty MaximumProperty =
DependencyProperty.Register(
nameof(Maximum),
typeof(int),
typeof(NumericUpDown),
new PropertyMetadata(100));
public int Maximum
{
get => (int)GetValue(MaximumProperty);
set => SetValue(MaximumProperty, value);
}
private void Up_Click(object sender, RoutedEventArgs e)
{
if (Value < Maximum)
Value++;
}
private void Down_Click(object sender, RoutedEventArgs e)
{
if (Value > Minimum)
Value--;
}
}
}
Dependency properties make the NumericUpDown control flexible and reusable by allowing:
- Two-way data binding with ViewModels
- XAML configuration (e.g., setting Minimum and Maximum values)
- Automatic UI updates when values change
- MVVM compatibility without tightly coupling logic to the UI
Using the Control in a View
First, import the namespace:xmlns:controls="clr-namespace:YourApp.Controls"Then use the control:
<controls:NumericUpDown Value="{Binding Quantity}" Minimum="1" Maximum="50"/>
This binds the numeric value directly to a ViewModel property.
Summary
This approach is ideal for applications that require precise numeric input without relying on third-party libraries. Creating a NumericUpDown control in pure WPF is straightforward and avoids unnecessary dependencies. By using a UserControl with dependency properties, you gain flexibility, reusability, and full MVVM support—all while keeping your project lightweight.
Thanks