dcsimg
Results 1 to 9 of 9
  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Aug 2005
    Posts
    214

    Using comma and dot in same projects

    My software can be used by users that can be use different decimal system like (commo or dot) and they can share the files.
    Therefore i would like develop code with working both comma and dot decimal system. For example user can enter value to textbox as 1.25 or 1,25 in same form and in the same time.
    Thus, if user (with working comma system) save file project file and another user (with working dot system) can succefully open this file.

    Do you have any offer for this solution ?

    Best regards

  2. #2
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    39,811

    Re: Using comma and dot in same projects

    Don't use a TextBox for numeric entry, use a NumericUpDown instead.

    The NumericUpDown is designed for numbers, and will display and interpret them correctly according to the settings of the computer it is running on (and force the user to enter valid values, without you having to write any code for it). When you read the .Value property you get a number rather than text, so it can be used in calculations and stored safely.


    As for how to safely store a numeric value to a file, that depends on what kind of file it is, and what code you are currently using to save it.

    If it is a database then you just need to use a numeric data type, but if it is a text based file (including .CSV and .XML and many more) then you will need to work out how to save/load it appropriately (which may mean the file always uses a dot as the decimal separator, or you store header information to the file to indicate whether it is dot or comma).

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Aug 2005
    Posts
    214

    Re: Using comma and dot in same projects

    Hi si_the_geek

    Thanks for your answer.

    NumericUpDown control is not proper way for my projects.

    Do you have an another solution.
    Meanwhile i'm using text based file while saving


    Best regards

  4. #4
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    39,811

    Re: Using comma and dot in same projects

    Quote Originally Posted by levent View Post
    NumericUpDown control is not proper way for my projects.

    Do you have an another solution.
    I might be able to think of one, but I would need to know what the limitations are... for example, what is the reason a NumericUpDown (which is the easiest and safest thing for this kind of situation) isn't appropriate for you? (is it just that you haven't used one before? ...or that you don't want the optional arrow buttons on it? ..or something else)

    Meanwhile i'm using text based file while saving
    Ok, what code are you using to save and load the file?

  5. #5

    Thread Starter
    Addicted Member
    Join Date
    Aug 2005
    Posts
    214

    Re: Using comma and dot in same projects

    Hİ,

    The data input range is very wide in my software therefore data entry with using numericupdown control is not very effective in terms of the user.

    I'm using print and input command for saving and loading files.

  6. #6
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    39,811

    Re: Using comma and dot in same projects

    Quote Originally Posted by levent View Post
    The data input range is very wide in my software therefore data entry with using numericupdown control is not very effective in terms of the user.
    That doesn't matter... they can use it in exactly the same way as a TextBox, so it doesn't have any additional problem there (only additional features, most of them are for your benefit and the user wont notice them at all).

    I'm using print and input command for saving and loading files.
    We need to see the actual code (at least the parts that relate to one of the 'numeric' values).

  7. #7
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Using comma and dot in same projects

    The Parse() methods of every numeric type are very flexible. You should read their documentation to become familiar with all they can do.

    In this case, if you pass an appropriate NumberStyles value to the method, it will allow digit separators and decimal points. As a bonus, it always uses what the system settings say the user wants. So on machines that display "one thousand" as "1.000", it will expect the user to type "1.000". The simplest thing that might work is:
    Code:
    Dim value = Double.Parse("1,000.45", System.Globalization.NumberStyles.Number)
    You can read the documentation to see if there are more appropriate values for your case.

    However, since you're saving files, you have a new layer of headache on top of this. File contents don't magically update as they cross systems.

    Suppose my friend uses "." for decimal point and I use ",". She saves a file with the value "1.234", then sends that file to me. I open it, and get "one and two hundred thirty four thousandths" instead of "one thousand two hundred thirty four".

    The safest thing to do in this case is to use binary files. The commas and dots are things the computer adds later, it won't get confused if you use binary files.

    If you HAVE to write text, you have to solve the problem some kind of way. The easiest thing to do here is to save the files with the "invariant" culture. That's a set of culture rules that is the same on all machines and cannot be uninstalled. So no matter what the user's settings are, if you save and load with that culture things will work on all machines:
    Code:
    Imports System.Globalization
    
    '...
    
    Dim value As Double = Double.Parse(yourFile.ReadLine(), NumberStyles.Number, CultureInfo.InvariantCulture)
    
    yourFile.WriteLine(someNumber.ToString(CultureInfo.InvariantCulture))
    If you want users to hand-edit those files, you have a very large mess on your hands. I think it's possible to implement that, but you're going to have to write at least two custom IFormatProviders. You'll want to make your file format have a marker that tells the program which one to use, if you don't do that then you either have to make the user tell you or try guessing. It's a lot more difficult.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  8. #8

    Thread Starter
    Addicted Member
    Join Date
    Aug 2005
    Posts
    214

    Re: Using comma and dot in same projects

    Thanks for your reply Sitten Spynne

  9. #9
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    9,318

    Re: Using comma and dot in same projects

    I generally do a lot of work for this one guy who uses touch screens and so while I loved how the NumericUpDown control handled numeric input, the spinners were too little for the users to really use. Because of this, I decided to create a virtual keypad form and it has really worked out for me. I have no problem sharing it:
    File: FormKeypad.Designer.vb
    Code:
    Code:
    Public Class FormKeypad
    
        Private _allowDecimal As Boolean = False
        ''' <summary>
        ''' Gets or sets the value that determines if the form will allow for a decimal place
        ''' </summary>
        ''' <returns>System.Boolean</returns>
        ''' <remarks>If the property is True, it will only allow for a single decimal place. Therefore, values such as IP addresses (127.0.0.1) cannot be entered.</remarks>
        Public Property AllowDecimal() As Boolean
            Get
                Return _allowDecimal
            End Get
            Set(ByVal value As Boolean)
                _allowDecimal = value
            End Set
        End Property
    
        Private _value As Double = 0
        ''' <summary>
        ''' Gets or sets the value that is displayed in the TextBox
        ''' </summary>
        ''' <returns>System.Double</returns>
        Public Property Value() As Double
            Get
                Return _value
            End Get
            Set(ByVal value As Double)
                _value = value
            End Set
        End Property
    
        'Form Events
        Private Sub frmKeypad_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            'Set the text of the keypad input
            ButtonDecimal.Text = System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator
    
            'Toggle the back button
            Dim back As Binding = ButtonBack.DataBindings.Add("Enabled", Me.TextBoxValue, "Text", True, DataSourceUpdateMode.OnPropertyChanged)
            AddHandler back.Format, Sub(s As Object, args As ConvertEventArgs) args.Value = Not String.IsNullOrWhiteSpace(args.Value.ToString)
            AddHandler back.Parse, Sub(s As Object, args As ConvertEventArgs) args.Value = Me.TextBoxValue.Text
            ButtonBack.Enabled = Not String.IsNullOrWhiteSpace(Me.TextBoxValue.Text)
    
            'Toggle the decimal button
            Dim dec As Binding = ButtonDecimal.DataBindings.Add("Enabled", Me.TextBoxValue, "Text", True, DataSourceUpdateMode.OnPropertyChanged)
            AddHandler dec.Format, Sub(s As Object, args As ConvertEventArgs) args.Value = Not String.IsNullOrWhiteSpace(args.Value.ToString) AndAlso args.Value.ToString.IndexOf("."c) = -1 AndAlso _allowDecimal
            AddHandler dec.Parse, Sub(s As Object, args As ConvertEventArgs) args.Value = Me.TextBoxValue.Text
            ButtonDecimal.Enabled = Not String.IsNullOrWhiteSpace(Me.TextBoxValue.Text.ToString) AndAlso Me.TextBoxValue.Text.ToString.IndexOf("."c) = -1 AndAlso _allowDecimal
    
            'Move the caret to the end of the line
            TextBoxValue.SelectionStart = TextBoxValue.TextLength
        End Sub
    
        Private Sub frmKeypad_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
            If e.KeyCode = Keys.Return Then
                'Submit the form
                ButtonSubmit.PerformClick()
    
                e.Handled = True
            ElseIf e.KeyCode = Keys.Back Then
                'Click on the backspace button
                ButtonBack.PerformClick()
    
                e.Handled = True
            End If
        End Sub
    
        Private Sub frmKeypad_KeyPress(sender As Object, e As KeyPressEventArgs) Handles MyBase.KeyPress
            'Invoke the click of the button
            Dim btn As Button = TableLayoutPanel_Keypad.Controls.OfType(Of Button).SingleOrDefault(Function(b) b.Text.Equals(e.KeyChar))
            If btn IsNot Nothing Then
                btn.PerformClick()
            End If
        End Sub
    
        'Button events
        Private Sub Button_Click(sender As Object, e As EventArgs) Handles ButtonDecimal.Click, Button9.Click, Button8.Click, Button7.Click, Button6.Click, Button5.Click, Button4.Click, Button3.Click, Button2.Click, Button1.Click, Button0.Click
            'Append the text of the Button that was just clicked
            TextBoxValue.AppendText(DirectCast(sender, Button).Text)
    
            'Refocus to the TextBox
            TextBoxValue.Select()
        End Sub
    
        Private Sub ButtonBack_Click(sender As Object, e As EventArgs) Handles ButtonBack.Click
            'Remove the last character
            If TextBoxValue.TextLength > 0 Then TextBoxValue.Text = TextBoxValue.Text.Substring(0, TextBoxValue.TextLength - 1)
    
            'Refocus to the TextBox
            TextBoxValue.Select()
        End Sub
    
        Private Sub ButtonSubmit_Click(sender As Object, e As EventArgs) Handles ButtonSubmit.Click
            If Double.TryParse(Me.TextBoxValue.Text, _value) Then
                'Submit the form
                Me.DialogResult = DialogResult.OK
            Else
                'Invalid input
                Me.DialogResult = DialogResult.Abort
            End If
    
            'Close the form
            Me.Close()
        End Sub
    
        'TextBox events
        Private Sub TextBoxValue_GotFocus(sender As Object, e As EventArgs) Handles TextBoxValue.GotFocus
            'Hide the blinking I in the TextBox
            Me.HideCaret(TextBoxValue.Handle)
        End Sub
    
        'Win32 API
        Private Declare Function HideCaret Lib "user32.dll" (ByVal hWnd As IntPtr) As Boolean
    
    End Class
    Then to launch the dialog, I would use the following code for a read-only TextBox:
    Code:
        'Numeric input click
        Private Sub NumericInput_Click(ByVal sender As Object, ByVal e As EventArgs) Handles MyReadOnlyTextBox.Click
    
            'Show the keypad
            Using frmKeypad As FormKeypad = New FormKeypad
                With frmKeypad
                    .AllowDecimal = True 'Allow for decimals
                    .TextBoxValue.Text = DirectCast(sender, TextBox).Text 'Set the existing value (if applicable)
    
                    'Show the dialog
                    Dim result As DialogResult = frmKeypad.ShowDialog
                    If result = DialogResult.OK Then
                        'Convert the Double value to a String and set the clicked TextBox's Text
                        DirectCast(sender, TextBox).Text = .Value.ToString
                    ElseIf result = DialogResult.Abort AndAlso String.IsNullOrWhiteSpace(.TextBoxValue.Text) Then
                        DirectCast(sender, TextBox).Text = String.Empty
                    End If
                End With
            End Using
        End Sub
    
        'Numeric input key press
        Private Sub NumericInput_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) Handles MyReadOnlyTextBox.KeyPress
    
            If Char.IsDigit(e.KeyChar) Then
                'Show the keypad
                Using frmKeypad As FormKeypad = New FormKeypad
                    With frmKeypad
                        .AllowDecimal = True 'Allow for decimals
                        .TextBoxValue.Text = DirectCast(sender, TextBox).Text & e.KeyChar 'Set the existing value (if applicable) along with the new KeyChar
    
                        'Show the dialog
                        Dim result As DialogResult = .ShowDialog()
                        If result = DialogResult.OK Then
                            'Convert the Double value to a String and set the clicked TextBox's Text
                            DirectCast(sender, TextBox).Text = .Value.ToString
                        ElseIf result = DialogResult.Abort AndAlso String.IsNullOrWhiteSpace(.TextBoxValue.Text) Then
                            DirectCast(sender, TextBox).Text = String.Empty
                        End If
                    End With
                End Using
            End If
        End Sub

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width