• XAML Logo

I needed to Limit several TextBoxes in my WPF MVVM application to only allow Numeric Characters.

I stumbled upon a very useful post by Jermey Likeness which described a method using Attached Behaviours, which worked well for me;

http://csharperimage.jeremylikness.com/2009/10/silverlight-behaviors-and-triggers_07.html

I modified this code slightly to allow for Decimal point control also.

The VB.net Code is as follows;

[fusion_builder_container hundred_percent=”yes” overflow=”visible”][fusion_builder_row][fusion_builder_column type=”1_1″ background_position=”left top” background_color=”” border_size=”” border_color=”” border_style=”solid” spacing=”yes” background_image=”” background_repeat=”no-repeat” padding=”” margin_top=”0px” margin_bottom=”0px” class=”” id=”” animation_type=”” animation_speed=”0.3″ animation_direction=”left” hide_on_mobile=”no” center_content=”no” min_height=”none”][vbnet]

Imports System.Collections.ObjectModel

Namespace Behaviours

Public Class clsTextBoxFilters

#Region "Variables"

Private Shared ReadOnly _controlKeys As List(Of Key) = New List(Of Key) From {Key.Back,
Key.CapsLock,
Key.LeftCtrl,
Key.RightCtrl,
Key.Down,
Key.[End],
Key.Enter,
Key.Escape,
Key.Home,
Key.Insert,
Key.Left,
Key.PageDown,
Key.PageUp,
Key.Right,
Key.LeftShift,
Key.RightShift,
Key.Tab,
Key.Up,
Key.Decimal,
Key.OemPeriod}

#End Region

#Region "Helper Functions"

”’
”’ Check if the key is a Numeric
”’
”’
”’
”’
Private Shared Function _IsDigit(key__1 As Key) As Boolean
Dim shiftKey As Boolean = (Keyboard.Modifiers And ModifierKeys.Shift) <> 0
Dim retVal As Boolean
If key__1 >= Key.D0 AndAlso key__1 <= Key.D9 AndAlso Not shiftKey Then
retVal = True
Else
retVal = key__1 >= Key.NumPad0 AndAlso key__1 <= Key.NumPad9
End If
Return retVal
End Function

#End Region

#Region "Getters and Setters"

”’
”’ Get the value of the Numeric Filter Dependancy Property
”’
”’
”’
”’
Public Shared Function GetIsPositiveNumericFilter(src As DependencyObject) As Boolean
Return CBool(src.GetValue(IsPositiveNumericFilterProperty))
End Function

”’
”’ Set the Value of the Numeric Filter Dependancy Property
”’
”’
”’
”’
Public Shared Sub SetIsPositiveNumericFilter(src As DependencyObject, value As Boolean)
src.SetValue(IsPositiveNumericFilterProperty, value)
End Sub

”’
”’ Get the Value of the IsIntegerOnly Dependancy Property
”’
”’
”’
”’
Public Shared Function GetIsIntegerOnly(src As DependencyObject) As Boolean
Return CBool(src.GetValue(IsIntegerOnlyProperty))
End Function

”’
”’ Sets the Value of the IsIntegerOnly Dependancy Property
”’
”’
”’
”’
Public Shared Sub SetIsIntegerOnly(src As DependencyObject, value As Boolean)
src.SetValue(IsIntegerOnlyProperty, value)
End Sub

#End Region

#Region "Dependancy Properties"

Public Shared IsPositiveNumericFilterProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsPositiveNumericFilter", GetType(Boolean), GetType(clsTextBoxFilters), New PropertyMetadata(False, AddressOf IsPositiveNumericFilterChanged))
Public Shared IsIntegerOnlyProperty As DependencyProperty = DependencyProperty.Register("IsIntegerOnly", GetType(Boolean), GetType(clsTextBoxFilters), Nothing)

#End Region

#Region "Dependancy Property Change Handlers"

”’
”’ Determines if the Behaviour is active, adds the KeyDown event Handler
”’
”’
”’
”’
Public Shared Sub IsPositiveNumericFilterChanged(src As DependencyObject, args As DependencyPropertyChangedEventArgs)
If src IsNot Nothing AndAlso TypeOf src Is TextBox Then
Dim textBox As TextBox = TryCast(src, TextBox)

If CBool(args.NewValue) Then
AddHandler textBox.KeyDown, AddressOf _TextBoxPositiveNumericKeyDown
End If
End If
End Sub

#End Region

#Region "Event Handlers"

”’
”’ KeyDown event… Check if the Key is valid… If so allow, if not then ignore the key
”’
”’
”’
”’
Private Shared Sub _TextBoxPositiveNumericKeyDown(sender As Object, e As KeyEventArgs)
Dim handled As Boolean = True

Dim txtSender As TextBox = DirectCast(sender, TextBox)

If e.Key = Key.OemPeriod Then ‘Is the current key a Decimal Point?

If txtSender.GetValue(IsIntegerOnlyProperty) = True Then ‘Is this an Integer Only TextBox?

handled = True

ElseIf InStr(txtSender.Text, ".") = 0 And Len(txtSender.Text) > 0 Then ‘We only want 1 decimal point, and it can’t be the first digit!

handled = False

Else ‘Otherwise ignore the keypress

handled = True

End If

ElseIf _controlKeys.Contains(e.Key) OrElse _IsDigit(e.Key) Then ‘Is the Key a numeric or an allowed key?

handled = False

End If

e.Handled = handled

End Sub

#End Region

End Class

End Namespace

[/vbnet]

The XAML to add to the UserControl Header Namespaces is;

[/fusion_builder_column][fusion_builder_column type=”1_1″ background_position=”left top” background_color=”” border_size=”” border_color=”” border_style=”solid” spacing=”yes” background_image=”” background_repeat=”no-repeat” padding=”” margin_top=”0px” margin_bottom=”0px” class=”” id=”” animation_type=”” animation_speed=”0.3″ animation_direction=”left” hide_on_mobile=”no” center_content=”no” min_height=”none”][xml]
xmlns:Behaviors="clr-namespace:CriticalPath_WPF_MVVM_EF.Behaviours"
[/xml]

The XAML to add to the TextBox Is;

[/fusion_builder_column][fusion_builder_column type=”1_1″ background_position=”left top” background_color=”” border_size=”” border_color=”” border_style=”solid” spacing=”yes” background_image=”” background_repeat=”no-repeat” padding=”” margin_top=”0px” margin_bottom=”0px” class=”” id=”” animation_type=”” animation_speed=”0.3″ animation_direction=”left” hide_on_mobile=”no” center_content=”no” min_height=”none”][xml]
Behaviors:clsTextBoxFilters.IsPositiveNumericFilter="True" Behaviors:clsTextBoxFilters.IsIntegerOnly="True"
[/xml]

Very handy![/fusion_builder_column][/fusion_builder_row][/fusion_builder_container]

By |2017-07-24T08:33:18+01:00January 1st, 2013|.Net Framework, MVVM, Tips, VB.net, WPF|0 Comments

About the Author:

Leave A Comment