Textboxes for numeric input in WPF.
- DoubleBox
- IntBox
- DecimalBox
- FloatBox
- ShortBox
- Easy to add more
- 1. Samples
- 2. Features:
- 3. Validation
- 4. Formatting
- 5. Spinners
- 5. Attached properties
- 6. Style and Template keys
The Text
property is used internally and will throw if you bind to it.
Bind the Value
property of the boxes like this:
<numericInput:DoubleBox Value="{Binding DoubleValue}" />
<numeric:SpinnerDecorator>
<numeric:DoubleBox Value="{Binding Value,
ValidatesOnNotifyDataErrors=True}"
CanValueBeNull="{Binding CanValueBeNull}"
ValidationTrigger="PropertyChanged"
MaxValue="10"
MinValue="-10"
NumberStyles="AllowDecimalPoint,AllowLeadingSign"
RegexPattern="\1\d+(\.2\d+)"
StringFormat="N2"
AllowSpinners="True"
SpinUpdateMode="PropertyChanged"
Increment="{Binding Increment}"/>
</numeric:SpinnerDecorator>
- Validation
- Validates as you type even with UpdateSourceTrigger=LostFocus for the binding. Configurable via
ValidationTrigger
- Uses vanilla WPF validation
- If there is a validation error no value is sent to the viewmodel.
- Validates as you type even with UpdateSourceTrigger=LostFocus for the binding. Configurable via
- Works with WPF focus.
- Formatting using formatted view and edit view.
- Compatible with WPF undo/redo.
- SpinnerDecorator for up/down buttons.
Control when validation is performed, the default is LostFocus
to be consistent with vanilla WPF TextBox
Setting ValidationTrigger="PropertyChanged"
validates as you type even if the binding has UpdateSourceTrigger=LostFocus
.
Available as inheriting attached property: NumericBox.ValidationTrigger
Sets if empty textbox sends null to the binding source and is a legal value. Useful when binding to a double?
for example.
Available as inheriting attached property: NumericBox.CanValueBeNull
The minimum value. The default is null meaning that no validation on min is performed.
When using spinners clicking decrease truncates to min if it would decrement below min.
If user enters a value less than MinValue
the validation returns an IsLessThanValidationResult
With the content as a string Properties.Resources.Please_enter_a_value_greater_than_or_equal_to__0__
The message is localized using box.Culture
.
The maximum value. The default is null meaning that no validation on max is performed.
When using spinners clicking increase truncates to max if it would increment above max.
If user enters a value greater than MaxValue
the validation returns an IsGreaterThanValidationResult
With the content as a string Properties.Resources.Please_enter_a_value_less_than_or_equal_to__0__
The message is localized using box.Culture
.
The NumberStyles
used when parsing and formatting the value.
Ex if you want to allow leading sign or thousands.
The IFormatProvider
used when parsing and formatting the value.
The default value for culture is Thread.CurrentThread.CurrentUICulture
Available as inheriting attached property: NumericBox.Culture
A regex pattern used when validating the input.
If StringFormat
or DecimalDigits
are specified a TextBlock with the formatted text is overlaid when not focused.
The IFormatProvider
used when parsing and formatting the value.
The default value for culture is Thread.CurrentThread.CurrentUICulture
Available as inheriting attached property: NumericBox.Culture
The NumberStyles
used when parsing and formatting the value.
<numeric:DoubleBox NumberStyles="AllowDecimalPoint, AllowLeadingSign"
Value="{Binding Value}" />
The string format used in the formatted view.
Available as inheriting attached property: NumericBox.StringFormat
<numeric:DoubleBox Culture="sv-se"
StringFormat="#,0.00"
Value="{Binding Value}" />
DecimalDigits="3"
sets stringformat to F3
which means the value will always have three digits.
DecimalDigits="-3"
sets stringformat to 0.###
which means the value will be rendered with up to three digits.
If the user eneters more digits they are used in the Value binding. The formatted view will round the value.
Available as inheriting attached property: NumericBox.DecimalDigits
If you want to add up/down buttons you wrap the box in a spinnerdecorator liken this:
<numeric:SpinnerDecorator>
<numeric:DoubleBox AllowSpinners="True"
Increment="10"
Value="{Binding Value}" />
</numeric:SpinnerDecorator>
The spinner decorator derives from Control
so it can be templated for easy styling.
How big change each increment/decrement is. Checked for overflow.
If the value is 9.5 and Increment="1"
and Max="10"
one click on increment will set the value to 10.
Controls if spinners are visible assuming the control is wrapped in a SpinnerDecorator
Controls how the IncreaseCommand
and the DecreaseCommand
behaves.
The default is AsBinding
meaning the value updates using the UpdateSourceTrigger
specified in the binding. Default is lostfocus.
If set to PropertyChanged
the binding source will be updated at each click even if the binding has UpdateSourceTrigger = LostFocus
This property inherits so it can be set for example on the Window
ex: numericInput:NumericBox.SpinUpdateMode = "PropertyChanged"
The boxes exposes two command for incrementing and decrementing the current value with Increment
clicking changes the text so it is undoable.
Controls what Culture to use.
Inherits so setting it on a panel or window sets it for all child controls inheriting from BaseBox
.
Sample:
<UserControl x:Class="Gu.Wpf.NumericInput.Demo.DemoView"
...
xmlns:numeric="http://gu.se/NumericInput">
<Grid numeric:NumericBox.Culture="sv-se">
...
<numeric:DoubleBox .../>
<numeric:DoubleBox .../>
...
</Grid>
Controls when validation is performed.
Inherits so setting it on a panel or window sets it for all child controls inheriting from BaseBox
.
Sample:
<UserControl x:Class="Gu.Wpf.NumericInput.Demo.DemoView"
...
xmlns:numeric="http://gu.se/NumericInput">
<Grid numeric:NumericBox.ValidationTrigger="PropertyChanged">
...
<numeric:DoubleBox .../>
<numeric:DoubleBox .../>
...
</Grid>
Controls if empty means null and is a legal value.
Inherits so setting it on a panel or window sets it for all child controls inheriting from BaseBox
.
Sample:
<UserControl x:Class="Gu.Wpf.NumericInput.Demo.DemoView"
...
xmlns:numeric="http://gu.se/NumericInput">
<Grid numeric:NumericBox.CanValueBeNull="True">
...
<numeric:DoubleBox .../>
<numeric:DoubleBox .../>
...
</Grid>
Controls if empty means null and is a legal value.
Inherits so setting it on a panel or window sets it for all child controls inheriting from BaseBox
.
Sample:
<UserControl x:Class="Gu.Wpf.NumericInput.Demo.DemoView"
...
xmlns:numeric="http://gu.se/NumericInput">
<Grid numeric:NumericBox.NumberStyles="AllowDecimalPoint, AllowLeadingSign">
...
<numeric:DoubleBox .../>
<numeric:DoubleBox .../>
...
</Grid>
Controls how many decimal digits are shown.
Inherits so setting it on a panel or window sets it for all child controls inheriting from BaseBox
.
Sample:
<UserControl x:Class="Gu.Wpf.NumericInput.Demo.DemoView"
...
xmlns:numeric="http://gu.se/NumericInput">
<Grid numeric:NumericBox.StringFormat="F2">
...
<numeric:DoubleBox .../>
<numeric:DoubleBox .../>
...
</Grid>
Controls how many decimal digits are shown.
Inherits so setting it on a panel or window sets it for all child controls inheriting from DecimalDigitsBox<T>
.
Sample:
<UserControl x:Class="Gu.Wpf.NumericInput.Demo.DemoView"
...
xmlns:numeric="http://gu.se/NumericInput">
<Grid numeric:NumericBox.DecimalDigits="-2">
...
<numeric:DoubleBox .../>
<numeric:DoubleBox .../>
...
</Grid>
Allows spinners on all child NumericBoxes.
Inherits so setting it on a panel or window sets it for all child controls inheriting from BaseBox
.
Sample:
<UserControl x:Class="Gu.Wpf.NumericInput.Demo.DemoView"
...
xmlns:numeric="http://gu.se/NumericInput">
<Grid numeric:NumericBox.AllowSpinners="True">
...
<numeric:DoubleBox .../>
<numeric:DoubleBox .../>
...
</Grid>
Selects all text in a textbox whgen it gets keyboard focus.
Inherits so setting it on a panel or window sets it for all child controls inheriting from TextBox
.
Sample:
<UserControl x:Class="Gu.Wpf.NumericInput.Demo.DemoView"
...
xmlns:select="http://gu.se/Select">
<Grid select:TextBox.SelectAllOnGotKeyboardFocus="True">
...
<numeric:DoubleBox .../>
<TextBox .../>
...
</Grid>
Selects all text in a textbox on click.
Inherits so setting it on a panel or window sets it for all child controls inheriting from TextBox
.
Sample:
<UserControl x:Class="Gu.Wpf.NumericInput.Demo.DemoView"
...
xmlns:select="http://gu.se/Select">
<Grid select:TextBox.SelectAllOnClick="True">
...
<numeric:DoubleBox .../>
<TextBox .../>
...
</Grid>
Selects all text in a textbox on doubleclick.
Inherits so setting it on a panel or window sets it for all child controls inheriting from TextBox
.
Sample:
<UserControl x:Class="Gu.Wpf.NumericInput.Demo.DemoView"
...
xmlns:select="http://gu.se/Select">
<Grid select:TextBox.SelectAllOnDoubleClick="True">
...
<numeric:DoubleBox .../>
<TextBox .../>
...
</Grid>
Captures enter key and cycles focus to next control.
Inherits so setting it on a panel or window sets it for all child controls inheriting from TextBox
.
Sample:
<UserControl x:Class="Gu.Wpf.NumericInput.Demo.DemoView"
...
xmlns:select="http://gu.se/Select">
<Grid select:TextBox.MoveFocusOnEnter="True"
KeyboardNavigation.TabNavigation="Cycle">
...
<numeric:DoubleBox .../>
<TextBox .../>
...
</Grid>
Shows onscreen keyboard on touch enter for all controls inheriting from TextBox
.
Inherits so setting it on a panel or window sets it for all child controls inheriting from TextBox
.
Sample:
<UserControl x:Class="Gu.Wpf.NumericInput.Demo.DemoView"
...
xmlns:touch="http://gu.se/Touch">
<Grid touch:TextBox.ShowTouchKeyboardOnTouchEnter="True">
...
<numeric:DoubleBox .../>
<TextBox .../>
...
</Grid>
NumericBox.BaseBoxStyleKey
NumericBox.SpinnersTemplateKey
NumericBox.SpinnerPathStyleKey
NumericBox.SpinnerButtonStyleKey