Option Strict On Imports System.Drawing Imports System.Windows.Forms Imports System.ComponentModel Public Class cTextboxEx Inherits System.Windows.Forms.TextBox Implements IDisabled 'Tous les événements interceptés doivent être relancés 'Public Shadows Event MouseDown As EventHandler 'Public Shadows Event TextChanged As EventHandler Private mblnClicked As Boolean Private mclrBackColorDisabled As Color = Color.Gainsboro Private mclrForeColorDisabled As Color = SystemColors.WindowText Public Property BackColorDisabled() As System.Drawing.Color Implements IDisabled.BackColorDisabled Get Return mclrBackColorDisabled End Get Set(ByVal Value As System.Drawing.Color) mclrBackColorDisabled = Value End Set End Property Public Property ForeColorDisabled() As System.Drawing.Color Implements IDisabled.ForeColorDisabled Get Return mclrForeColorDisabled End Get Set(ByVal Value As System.Drawing.Color) mclrForeColorDisabled = Value End Set End Property Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) MyBase.OnPaint(e) Dim TextBrush As SolidBrush Dim sf As New StringFormat 'ref: http://www.dotnet247.com/247reference/msgs/54/271869.aspx Select Case Me.TextAlign Case HorizontalAlignment.Center sf.Alignment = StringAlignment.Center Case HorizontalAlignment.Left sf.Alignment = StringAlignment.Near Case HorizontalAlignment.Right sf.Alignment = StringAlignment.Far End Select Dim rDraw As RectangleF = RectangleF.op_Implicit(Me.ClientRectangle) rDraw.Inflate(0, 0) If Me.Enabled Then TextBrush = New SolidBrush(Me.ForeColor) Else TextBrush = New SolidBrush(Me.ForeColorDisabled) Dim BackBrush As New SolidBrush(Me.BackColorDisabled) e.Graphics.FillRectangle(BackBrush, 0.0F, 0.0F, Me.Width, Me.Height) BackBrush.Dispose() BackBrush = Nothing End If 'If (Me.PasswordChar Is Nothing) OrElse (Me.PasswordChar = "") Then If Convert.ToInt32(Me.PasswordChar) = 0 Then e.Graphics.DrawString(Me.Text, Me.Font, TextBrush, rDraw, sf) Else e.Graphics.DrawString("".PadRight(Me.Text.Length, Me.PasswordChar), Me.Font, TextBrush, rDraw, sf) End If TextBrush.Dispose() TextBrush = Nothing sf.Dispose() sf = Nothing End Sub Protected Overrides Sub OnEnabledChanged(ByVal e As System.EventArgs) MyBase.OnEnabledChanged(e) If Not Me.Enabled Then Me.SetStyle(ControlStyles.UserPaint, True) Else Me.SetStyle(ControlStyles.UserPaint, False) End If Me.Invalidate() End Sub Protected Overrides Sub OnEnter(ByVal e As System.EventArgs) MyBase.OnEnter(e) Me.SelectAll() End Sub Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs) If Not mblnClicked Then Me.SelectAll() mblnClicked = True End If 'RaiseEvent MouseDown(Me, e) MyBase.OnMouseDown(e) End Sub Protected Overrides Sub OnTextChanged(ByVal e As System.EventArgs) If Me.TextLength > Me.MaxLength Then Me.Text = Me.Text.Substring(0, Me.MaxLength) End If MyBase.OnTextChanged(e) ' RaiseEvent TextChanged(Me, e) End Sub Protected Overrides Sub CreateHandle() 'Pour mettre le contenu du textbox vide à la création If Me.DesignMode Then Me.Text = "" End If MyBase.CreateHandle() End Sub End Class Option Strict On '===================================================================================== ' Classe : NumericTextbox.vb ' ' Auteur : Eric Moreau ' ' Description : System.Windows.Forms.TextBox Extender ' ' Utilisation : 1. Add a regular TextBox to your form ' 2. In the " Windows Form Designer generated code " section, ' replace System.Windows.Forms.TextBox by NumericTextBox (2 places) ' ' Historique : ' Auteur Date Intervention ' ----------------- --------------- ------------------------------------------------- ' Eric Moreau 2003/10/25 Création '===================================================================================== Imports System.ComponentModel Public Class cTextboxNumericEx ' Inherits System.Windows.Forms.TextBox Inherits cTextboxEx #Region " Windows Form Designer generated code " Public Sub New() MyBase.New() 'This call is required by the Windows Form Designer. InitializeComponent() 'Add any initialization after the InitializeComponent() call CustomInitialization() End Sub 'UserControl overrides dispose to clean up the component list. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub 'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer 'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor. Friend WithEvents ErrorProvider1 As System.Windows.Forms.ErrorProvider <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() Me.ErrorProvider1 = New System.Windows.Forms.ErrorProvider ' 'S2iNumericTextBox ' End Sub #End Region #Region " Members " Private mblnErrorProviderVisible As Boolean Private mbytNumberDecimals As Byte Private mbytNumberDigits As Byte Private mdecDefaultValue As Decimal Private mdecValueMax As Decimal Private mdecValueMin As Decimal Private mintErrorLanguage As enuLangueMessage Private mstrDisplayFormat As String Public Event ValidationError(ByVal sender As Object, ByVal e As S2iNumericTBEventArgs) Enum enuErrors ErrNone ErrTooManyMinusSign ErrMinusSignMisplaced ErrNegativeNotAllowed ErrTooManyDot ErrDotNotAllowed ErrLessThenMin ErrGreaterThenMax ErrInvalidValue ErrInvalidChar ErrEmptyValue ErrTooManyDigits ErrTooManyDecimals ErrCannotApplyFormat ErrPasteCanceled End Enum Enum enuLangueMessage English Francais End Enum #End Region '-- Members #Region " Methods " Protected Overrides Sub CreateHandle() Me.Text = mdecDefaultValue.ToString MyBase.CreateHandle() End Sub #Region " Public methods " '=========================================================================================================== '=== Returns wheter the textbox content is valid or not '=========================================================================================================== Public Function IsValid() As Boolean Return Me.ValidateFieldContent(Decimal.Parse(Me.Text, Globalization.NumberStyles.Any).ToString) End Function #End Region '-- Public methods #Region " Protected methods " <System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _ Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) Const WM_PASTE As Integer = &H302 ' Listen for operating system messages Select Case m.Msg Case WM_PASTE Dim iData As System.Windows.Forms.IDataObject = System.Windows.Forms.Clipboard.GetDataObject() Dim s As String = CType(iData.GetData(System.Windows.Forms.DataFormats.Text), String) If Not s = Nothing Then Dim strNewResult As String Dim strBeginning As String = Me.Text.Substring(0, Me.SelectionStart) Dim strEnding As String = Me.Text.Substring(Me.SelectionStart + Me.SelectionLength) strNewResult = strBeginning & s & strEnding 'Pour pallier le problème si le DisplayFormat ressemble à $ #,##0.00 'E.Moreau 2005.05.26 Dim objNF As System.Globalization.NumberFormatInfo = Threading.Thread.CurrentThread.CurrentCulture.NumberFormat strNewResult = strNewResult.Replace(objNF.CurrencySymbol, "").Replace(objNF.NumberGroupSeparator, "") If Me.ValidateFieldContent(strNewResult) Then 'OK - Resulting field will be OK MyBase.WndProc(m) Else 'The result of the paste would cause and invalid value so stop it SetError(enuErrors.ErrPasteCanceled, strNewResult) End If End If Case Else MyBase.WndProc(m) End Select End Sub #End Region '-- Protected methods #Region " Privates methods " '=========================================================================================================== '=== Calculates the number of a given character into a string '=========================================================================================================== Private Shared Function CountChar(ByVal pstrSource As String, ByVal pstrChar As String) As Integer Return pstrSource.Length - pstrSource.Replace(pstrChar, "").Length End Function '=========================================================================================================== '=== Custom initialization for the component '=========================================================================================================== Private Sub CustomInitialization() Me.DisplayFormat = "###,##0.00" Me.ErrorMessageLanguage = enuLangueMessage.Francais Me.NumberDecimals = 2 Me.NumberDigits = 6 Me.ValueMax = 999999.99D Me.ValueMin = -999999.99D End Sub '=========================================================================================================== '=== A centralized method to set the ErrorProvider control and to raise a custom event '=========================================================================================================== Private Sub SetError(ByVal pError As enuErrors, Optional ByVal pstrValue As String = "") Dim strMessageE As String Dim strMessageF As String Select Case pError Case enuErrors.ErrNone strMessageE = "" strMessageF = "" Case enuErrors.ErrEmptyValue strMessageE = "Field cannot be left empty!" strMessageF = "La valeur ne peut pas être laissé vide!" Case enuErrors.ErrTooManyMinusSign strMessageE = "Only one minus sign is allowed!" strMessageF = "Un seul symbole négatif est permis!" Case enuErrors.ErrMinusSignMisplaced strMessageE = "The minus sign must be placed at the beginning!" strMessageF = "Le symbole négatif doit être placé au début!" Case enuErrors.ErrTooManyDot strMessageE = "Only one decimal separator is allowed!" strMessageF = "Un seul séparateur de décimales est permis!" Case enuErrors.ErrDotNotAllowed strMessageE = "Decimal separator is not allowed!" strMessageF = "Le séparateur de décimal n'est pas permis!" Case enuErrors.ErrTooManyDigits strMessageE = "Too many digits! Only " & Me.NumberDigits.ToString & " allowed." strMessageF = "Trop de chiffres! Seulement " & Me.NumberDigits.ToString & " sont permis." Case enuErrors.ErrTooManyDecimals strMessageE = "Too many decimals! Only " & Me.NumberDecimals.ToString & " allowed." strMessageF = "Trop de décimales! Seulement " & Me.NumberDecimals.ToString & " sont permis." Case enuErrors.ErrLessThenMin strMessageE = "Value is less then the minimum allowed (" & Me.ValueMin.ToString & ")!" strMessageF = "La valeur est inférieure au minimum permis (" & Me.ValueMin.ToString & ")!" Case enuErrors.ErrGreaterThenMax strMessageE = "Value is greater then the maximum allowed (" & Me.ValueMax.ToString & ")!" strMessageF = "La valeur est supérieure au maximum permis (" & Me.ValueMax.ToString & ")!" Case enuErrors.ErrNegativeNotAllowed strMessageE = "Negative Values not allowed!" strMessageF = "Les valeurs négatives ne sont pas permises!" Case enuErrors.ErrInvalidValue strMessageE = "The field does not allow this value! (" & pstrValue & ")" strMessageF = "Valeur invalide! (" & pstrValue & ")" Case enuErrors.ErrInvalidChar strMessageE = "Character not allowed!" strMessageF = "Caractère invalide!" Case enuErrors.ErrCannotApplyFormat strMessageE = "Cannot apply the display format!" strMessageF = "Impossible d'appliquer la propriété DisplayFormat!" Case enuErrors.ErrPasteCanceled strMessageE = "The paste operation was canceled because it would result in an invalid value (" & pstrValue & ")!" strMessageF = "L'opération >Coller< a été annulé parce qu'elle causerait une valeur invalide (" & pstrValue & ")!" Case Else strMessageE = "Unkown error!" strMessageF = "Erreur inconnue!" End Select If ErrorMessageLanguage = enuLangueMessage.English Then If mblnErrorProviderVisible Then ErrorProvider1.SetError(Me, strMessageE) If strMessageE.Length > 0 Then RaiseEvent ValidationError(Me, New S2iNumericTBEventArgs(strMessageE, Me.Text)) End If Else If mblnErrorProviderVisible Then ErrorProvider1.SetError(Me, strMessageF) If strMessageF.Length > 0 Then RaiseEvent ValidationError(Me, New S2iNumericTBEventArgs(strMessageF, Me.Text)) End If End If End Sub '=========================================================================================================== '=== Validates many patters to be sure that the content of the field is valid. '=== Many of these validations cannot be done on the KeyPress event. '=== Others are also placed here to insure that paste or assignement is OK. '=========================================================================================================== Private Function ValidateFieldContent(ByVal pstrText As String) As Boolean SetError(enuErrors.ErrNone) 'Empty string not allowed If pstrText.Length = 0 Then SetError(enuErrors.ErrEmptyValue) Return False End If 'Invalid string Dim dblResult As Double If Not Double.TryParse(pstrText, Globalization.NumberStyles.Any, System.Threading.Thread.CurrentThread.CurrentCulture.NumberFormat, dblResult) Then SetError(enuErrors.ErrInvalidValue) Return False Else 'E.Moreau 2003/10/26 'Quand bindé sur un DECIMAL il retourne une valeur du style 123456.1200 ce qui cause une erreur si le champ ne peut contenir que 2 décimales! pstrText = dblResult.ToString End If 'Check to see the number of minus sign(-) and its position Select Case CountChar(pstrText, "-") Case 0 'OK No problems Case 1 If Not pstrText.StartsWith("-") Then SetError(enuErrors.ErrMinusSignMisplaced) Return False End If Case Else SetError(enuErrors.ErrTooManyMinusSign) Return False End Select 'Check to see if there is only one decimal separator Select Case CountChar(pstrText, System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator) Case 0 'OK, No problems Case 1 Dim intPos As Integer = pstrText.Replace("-", "").IndexOf(System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator) 'Check if the number of digits to the left of the decimal separator is OK If intPos > Me.NumberDigits Then SetError(enuErrors.ErrTooManyDigits) Return False End If 'Check if the number of digits to the right of the decimal separator is OK If pstrText.Replace("-", "").Length - (intPos + 1) > Me.NumberDecimals Then SetError(enuErrors.ErrTooManyDecimals) Return False End If Case Else SetError(enuErrors.ErrTooManyDot) Return False End Select 'Check min and max values If Me.ValueMin <> 0 OrElse Me.ValueMax <> 0 Then If dblResult < Me.ValueMin Then SetError(enuErrors.ErrLessThenMin) Return False End If If dblResult > Me.ValueMax Then SetError(enuErrors.ErrGreaterThenMax) Return False End If End If 'If we get through here, the value should be OK!!! Return True End Function '=========================================================================================================== '=== Validates a single character (called by the KeyPress event). '=========================================================================================================== Private Function ValidateKey() As Boolean 'E.Moreau 2005.01.05 - remove the selected text from the validation Dim strText As String If Me.SelectionLength > 0 Then strText = Me.Text.Replace(Me.SelectedText, "") Else strText = Me.Text End If Dim intPos As Integer = strText.IndexOf(System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator) If intPos = -1 Then If strText.Replace("-", "").Length = Me.NumberDigits Then SetError(enuErrors.ErrTooManyDigits) Return False End If Else If Me.SelectionStart > intPos Then 'Check if the number of digits to the right of the decimal separator is OK If strText.Length - (intPos + 1) >= Me.NumberDecimals Then SetError(enuErrors.ErrTooManyDecimals) Return False End If Else 'Check if the number of digits to the left of the decimal separator is OK If strText.IndexOf("-") = -1 Then If intPos >= Me.NumberDigits Then SetError(enuErrors.ErrTooManyDigits) Return False End If Else If intPos - 1 > Me.NumberDigits Then SetError(enuErrors.ErrTooManyDigits) Return False End If End If End If End If 'If we get through here, the value should be OK!!! Return True End Function #End Region '-- Privates methods #End Region '-- Methods #Region " Subclassed events " Private Sub SCEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Enter Try 'Remove formatting characters 'MyBase.Text = Decimal.Parse(Me.Text, Globalization.NumberStyles.Any).ToString 'Pour pallier le problème si le DisplayFormat ressemble à $ #,##0.00 'E.Moreau 2005.05.26 Dim objNF As System.Globalization.NumberFormatInfo = Threading.Thread.CurrentThread.CurrentCulture.NumberFormat MyBase.Text = Me.Text.Replace(objNF.CurrencySymbol, "").Replace(objNF.NumberGroupSeparator, "") Catch 'Nothing, just don't do it!!! End Try 'Me.SelectAll() End Sub Private Sub SCKeyPress(ByVal eventSender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles MyBase.KeyPress Dim KeyAscii As Integer = Convert.ToInt32(e.KeyChar) If KeyAscii = 8 Then '============================================================================================== '=== BackSpace '============================================================================================== 'Let it do its job ElseIf KeyAscii = 3 Then '============================================================================================== '=== CTRL-C '============================================================================================== 'Let it pass, validation will be done into the TextChanged event ElseIf KeyAscii = 22 Then '============================================================================================== '=== CTRL-V '============================================================================================== 'Let it pass, validation will be done into the WndProc method ElseIf KeyAscii = 26 Then '============================================================================================== '=== CTRL-Z '============================================================================================== 'Let it pass ElseIf e.KeyChar = System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator Then '============================================================================================== '=== Validation for . '============================================================================================== 'E.Moreau 2003.11.02 - remove the selected text from the validation Dim strText As String If Me.SelectionLength > 0 Then strtext = Me.Text.Replace(Me.SelectedText, "") Else strtext = Me.Text End If ' if we already have a period, throw it away If strText.IndexOf(".") >= 0 Then SetError(enuErrors.ErrTooManyDot) KeyAscii = 0 End If ' if we don't have decimals, throw it away If Me.NumberDecimals = 0 Then SetError(enuErrors.ErrDotNotAllowed) KeyAscii = 0 End If ElseIf e.KeyChar = "-" Then '============================================================================================== '=== Validation for - '============================================================================================== 'E.Moreau 2003.11.02 - remove the selected text from the validation Dim strText As String If Me.SelectionLength > 0 Then strtext = Me.Text.Replace(Me.SelectedText, "") Else strtext = Me.Text End If ' The number can only have one minus sign, so ' if we already have one, throw this one away If strText.IndexOf("-") >= 0 Then SetError(enuErrors.ErrTooManyMinusSign) KeyAscii = 0 End If ' if the insertion point is not sitting at zero ' (which is the beginning of the field), ' throw away the minus sign (because it's not ' valid except in first position) If Me.SelectionStart <> 0 Then SetError(enuErrors.ErrMinusSignMisplaced) KeyAscii = 0 End If ' do we allow negative numbers? If Me.ValueMin >= 0 Then SetError(enuErrors.ErrNegativeNotAllowed) KeyAscii = 0 End If ElseIf e.KeyChar >= "0" AndAlso e.KeyChar <= "9" Then '============================================================================================== '=== Validation for numbers '============================================================================================== If Not ValidateKey() Then 'SetError(enuErrors.ErrInvalidChar) KeyAscii = 0 End If Else SetError(enuErrors.ErrInvalidChar) KeyAscii = 0 End If If KeyAscii = 0 Then e.Handled = True End If End Sub Private Sub SCLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Leave Try Me.Text = CType(Me.Text, Decimal).ToString(Me.DisplayFormat, Nothing) Catch SetError(enuErrors.ErrCannotApplyFormat) Finally If Me.Text.Length = 0 Then Me.Text = mdecDefaultValue.ToString(Me.DisplayFormat, Nothing) End If End Try End Sub #End Region '-- Subclassed events #Region " Exposed Properties " #Region " Overrides " Public Overrides Property Text() As String Get Return MyBase.Text End Get Set(ByVal value As String) If value Is Nothing Then value = mdecDefaultValue.ToString End If If (value Is Nothing) OrElse (value.Trim.Length = 0) Then value = mdecDefaultValue.ToString End If 'Pour pallier le problème si le DisplayFormat ressemble à $ #,##0.00 'E.Moreau 2005.05.26 Dim objNF As System.Globalization.NumberFormatInfo = Threading.Thread.CurrentThread.CurrentCulture.NumberFormat value = value.Replace(objNF.CurrencySymbol, "").Replace(objNF.NumberGroupSeparator, "") Try value = Decimal.Parse(value, Globalization.NumberStyles.Any).ToString Catch ex As Exception value = mdecDefaultValue.ToString End Try If Me.ValidateFieldContent(value) Then 'MyBase.Text = Value 'E.Moreau 2003/10/26 'Formater quand une valeur est donnée à la propriété TEXT MyBase.Text = CType(value, Decimal).ToString(Me.DisplayFormat, Nothing) Else SetError(enuErrors.ErrInvalidValue, value) End If End Set End Property #End Region '-- Overrides #Region " Custom " 'This property contains the display format <CategoryAttribute("S2iNumericTextBox Properties"), _ DescriptionAttribute("The default value (also the value when the control is left empty).")> _ Public Property DefaultValue() As Decimal Get Return mdecDefaultValue End Get Set(ByVal Value As Decimal) mdecDefaultValue = Value End Set End Property 'This property contains the display format <CategoryAttribute("S2iNumericTextBox Properties"), _ DescriptionAttribute("The display format (passed to Decimal.ToString)")> _ Public Property DisplayFormat() As String Get Return mstrDisplayFormat End Get Set(ByVal Value As String) mstrDisplayFormat = Value End Set End Property 'This property dictates the language of error messages <CategoryAttribute("S2iNumericTextBox Properties"), _ DescriptionAttribute("The language of error messages")> _ Public Property ErrorMessageLanguage() As enuLangueMessage Get Return mintErrorLanguage End Get Set(ByVal Value As enuLangueMessage) mintErrorLanguage = Value End Set End Property 'This property contains the number of digits (to the right of the decimal point) <CategoryAttribute("S2iNumericTextBox Properties"), _ DescriptionAttribute("The number of digits (to the right of the decimal point)")> _ Public Property NumberDecimals() As Byte Get Return mbytNumberDecimals End Get Set(ByVal Value As Byte) mbytNumberDecimals = Value End Set End Property 'This property contains the maximum number of digits (decimals included) <CategoryAttribute("S2iNumericTextBox Properties"), _ DescriptionAttribute("The maximum number of digits (decimals excluded)")> _ Public Property NumberDigits() As Byte Get Return mbytNumberDigits End Get Set(ByVal Value As Byte) mbytNumberDigits = Value End Set End Property <CategoryAttribute("S2iNumericTextBox Properties"), _ DescriptionAttribute("The numeric value the textbox currently contains")> _ Public ReadOnly Property Value() As Decimal Get Try Return Decimal.Parse(Me.Text, Globalization.NumberStyles.Any) Catch ex As Exception Return 0 End Try End Get End Property <CategoryAttribute("S2iNumericTextBox Properties"), _ DescriptionAttribute("The maximum value the textbox can contain")> _ Public Property ValueMax() As Decimal Get Return mdecValueMax End Get Set(ByVal Value As Decimal) mdecValueMax = Value End Set End Property <CategoryAttribute("S2iNumericTextBox Properties"), _ DescriptionAttribute("The minimum value the textbox can contain")> _ Public Property ValueMin() As Decimal Get Return mdecValueMin End Get Set(ByVal Value As Decimal) mdecValueMin = Value End Set End Property #End Region '-- Custom #Region " Error Provider " <CategoryAttribute("S2iNumericTextBox Properties"), _ DescriptionAttribute("BlinkRate property of the Provider control.")> _ Public Property ErrProviderBlinkRate() As Integer Get Return ErrorProvider1.BlinkRate End Get Set(ByVal Value As Integer) ErrorProvider1.BlinkRate = Value End Set End Property <CategoryAttribute("S2iNumericTextBox Properties"), _ DescriptionAttribute("BlinkStyle property of the Provider control.")> _ Public Property ErrProviderBlinkStyle() As System.Windows.Forms.ErrorBlinkStyle Get Return ErrorProvider1.BlinkStyle End Get Set(ByVal Value As System.Windows.Forms.ErrorBlinkStyle) ErrorProvider1.BlinkStyle = Value End Set End Property <CategoryAttribute("S2iNumericTextBox Properties"), _ DescriptionAttribute("Icon property of the Provider control.")> _ Public Property ErrProviderIcon() As System.Drawing.Icon Get Return ErrorProvider1.Icon End Get Set(ByVal Value As System.Drawing.Icon) ErrorProvider1.Icon = Value End Set End Property <CategoryAttribute("S2iNumericTextBox Properties"), _ DescriptionAttribute("IconAlignment property of the Provider control.")> _ Public Property ErrProviderIconAlignment() As System.Windows.Forms.ErrorIconAlignment Get Return ErrorProvider1.GetIconAlignment(Me) End Get Set(ByVal Value As System.Windows.Forms.ErrorIconAlignment) ErrorProvider1.SetIconAlignment(Me, Value) End Set End Property <CategoryAttribute("S2iNumericTextBox Properties"), _ DescriptionAttribute("Will the Error Provider control be visible?")> _ Public Property ErrProviderVisible() As Boolean Get Return mblnErrorProviderVisible End Get Set(ByVal Value As Boolean) mblnErrorProviderVisible = Value End Set End Property #End Region '-- Error Provider #End Region '-- Exposed Properties End Class Public Class S2iNumericTBEventArgs Inherits EventArgs Private mstrMessage As String Private mstrValue As String Public Sub New(ByVal pMessage As String, ByVal pValue As String) Me.Message = pMessage Me.Value = pValue End Sub Public Property Message() As String Get Return mstrMessage End Get Set(ByVal value As String) mstrMessage = value End Set End Property Public Property Value() As String Get Return mstrValue End Get Set(ByVal value As String) mstrValue = value End Set End Property End Class