• 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”]

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

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”]

xmlns:Behaviors="clr-namespace:CriticalPath_WPF_MVVM_EF.Behaviours"

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”]

Behaviors:clsTextBoxFilters.IsPositiveNumericFilter="True" Behaviors:clsTextBoxFilters.IsIntegerOnly="True"

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

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

About the Author:

Leave A Comment