2017-07-03 4 views
1

Es sieht sehr seltsam aus, aber ich kann keine Online-Lösung für mein Problem finden! Zumindest in VB.NET.Automatische Nachkommastellen in Textfeld

Hier ist der Deal: Ich habe ein TextBox in einem Formular (begrenzt auf Zahlen von einem KeyPress Ereignis) und möchte zwei Dezimalstellen beibehalten, solange der Benutzer seine Daten eingibt.

Zum Beispiel, wenn die TextBox leer ist, dann, wenn der Benutzer drückt, sagen wir "2", die TextBox zeigt "0,02". Wenn der Benutzer dann "7" drückt, zeigt die TextBox "0,27" an. Dann wieder, mit der Taste „6“ ist, zeigt es „2,76“ und so weiter ...

ich es geschafft, dies mit dem Code für eine Dezimalstelle zu tun:

Select Case Me.TextBox.Text 
     Case "" 
     Case "," 
      Me.TextBox.Text = "" 
     Case Else 
      Me.TextBox.Text = Strings.Left(Replace(Me.TextBox.Text, ",", ""), Strings.Len(Replace(Me.TextBox.Text, ",", "")) - 1) & "," & Strings.Right(Replace(Me.TextBox.Text, ",", ""), 1) 
      Me.TextBox.SelectionStart = Len(Me.TextBox.Text) 
    End Select 

Bitte beachten Sie, dass: Dieser Code läuft auf einem TextChanged Ereignis; 2. Ich komme aus Portugal und hier verwenden wir ein Komma (",") anstelle eines Punktes (".") Für das Dezimaltrennzeichen.

Können Sie mir helfen, meinen Code so anzupassen, dass er mit zwei Dezimalstellen richtig funktioniert?

Jede Hilfe wird sehr geschätzt. Und wie immer, vielen Dank im Voraus.

+0

Anstatt den Text zu ändern, würde ich das 'Leave' -Ereignis verwenden, so dass Sie nicht mit den Dezimalzeichen kämpfen müssen, die Sie eingeben. Dann benutze 'ToString (0', um das Dezimalzeichen zu verwenden, das die Kultur verwendet – Plutonix

+0

Du verwendest das falsche Ereignis, benutze stattdessen das Validating-Ereignis. Decimal.TryParse + Decimal.ToString sollte nützlich sein. –

+0

https://stackoverflow.com/ questions/16035506/format-a-nummer-mit-kommas-und-dezimal-in-c-sharp-asp-net-mvc3 aC# antworten auf eine relativ ähnliche Frage, es könnte Ihnen helfen! – Kevin

Antwort

3

Hier ist eine benutzerdefinierte Klasse die ich gemacht habe, das tut, was Sie benötigen:

Public Class FactorDecimal 
    Private _value As String = "0" 

    Public DecimalPlaces As Integer 

    Public Sub AppendNumber(ByVal Character As Char) 
     If Char.IsNumber(Character) = False Then Throw New ArgumentException("Input must be a valid numerical character!", "Character") 
     _value = (_value & Character).TrimStart("0"c) 
    End Sub 

    Public Sub RemoveRange(ByVal Index As Integer, ByVal Length As Integer) 
     If _value.Length >= Me.DecimalPlaces + 1 AndAlso _ 
      Index + Length > _value.Length - Me.DecimalPlaces Then Length -= 1 'Exclude decimal point. 

     If Index + Length >= _value.Length Then Length = _value.Length - Index 'Out of range checking. 

     _value = _value.Remove(Index, Length) 

     If _value.Length = 0 Then _value = "0" 
    End Sub 

    Public Overrides Function ToString() As String 
     Dim Result As Decimal 
     If Decimal.TryParse(_value, Result) = True Then 
      'Divide Result by (10^DecimalPlaces) in order to get the amount of decimal places we want. 
      'For example: 2 decimal places => Result/(10^2) = Result/100 = x,xx. 
      Return (Result/(10^Me.DecimalPlaces)).ToString("0." & New String("0"c, Me.DecimalPlaces)) 
     End If 
     Return "<parse error>" 
    End Function 

    Public Sub New(ByVal DecimalPlaces As Integer) 
     If DecimalPlaces <= 0 Then DecimalPlaces = 1 
     Me.DecimalPlaces = DecimalPlaces 
    End Sub 
End Class 

Es funktioniert, indem wir dir Zahlen anhängen eine lange Reihe von numerischen Zeichen zu bilden (zB 3174 + 8 = 31748), dann, wenn Sie ToString() nennen es geschieht folgendes: (. ex "31748" => 31748.0)

  • es analysiert die lange Zahlenfolge in eine Dezimalzahl

    Er teilt das Dezimalsystem um 10 auf die Kraft der Höhe von Dezimalstellen angehoben Sie wollen (zum Beispiel: 2 Dezimalstellen =>31748.0/102 = 317.48).

  • Schließlich nennt es ToString() auf das Dezimalsystem mit dem Format 0.x - wo x eine sich wiederholende Menge von Nullen ist abhängig davon, wie viele Dezimalstellen Sie wollen (ex 2 Dezimalstellen =>0.00.).

HINWEIS: Diese Lösung passt sich an die Kultureinstellungen des aktuellen Systems und wird daher automatisch den Dezimalpunkt in dieser Kultur definiert verwenden. Zum Beispiel in einem amerikanischen (en-US) System wird es den Punkt verwenden: 317.48, während in einem schwedischen (.) oder portugiesischen (pt-PT) System wird es das Komma verwenden: 317,48.

Sie können es wie folgt verwenden:

Dim FactorDecimal1 As New FactorDecimal(2) 

Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress 
    If Char.IsNumber(e.KeyChar) = False Then 
     e.Handled = True 'Input was not a number. 
     Return 
    End If 

    FactorDecimal1.AppendNumber(e.KeyChar) 
    TextBox1.Text = FactorDecimal1.ToString() 
End Sub 

Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown 
    Dim TargetTextBox As TextBox = DirectCast(sender, TextBox) 
    e.SuppressKeyPress = True 

    Select Case e.KeyData 'In order to not block some standard keyboard shortcuts (ignoring paste since the pasted text won't get verified). 
     Case Keys.Control Or Keys.C 
      TargetTextBox.Copy() 
     Case Keys.Control Or Keys.X 
      TargetTextBox.Cut() 
     Case Keys.Control Or Keys.A 
      TargetTextBox.SelectAll() 
     Case Keys.Back, Keys.Delete 'Backspace or DEL. 
      FactorDecimal1.RemoveRange(TextBox1.SelectionStart, If(TextBox1.SelectionLength = 0, 1, TextBox1.SelectionLength)) 
      TextBox1.Text = FactorDecimal1.ToString() 
     Case Else 
      e.SuppressKeyPress = False 'Allow all other key presses to be passed on to the KeyPress event. 
    End Select 
End Sub 

Online-Test:http://ideone.com/fMcKJr

hoffe, das hilft!

1

Vielen Dank @Visual Vincent. Deine Methode funktioniert gut. Allerdings habe ich es geschafft, eine einfachere Art und Weise von finden zu tun, was ich durch den folgenden Code gefragt:

Private Sub TextBox_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox.KeyPress 
    If Not Char.IsDigit(e.KeyChar) And Not Char.IsControl(e.KeyChar) Then 
     e.Handled = True 
    End If 
End Sub 
Private Sub TextBox_TextChanged(sender As Object, e As EventArgs) Handles TextBox.TextChanged 
    Select Case Val(Replace(Me.TextBox.Text, ",", ".")) 
     Case 0 : Me.TextBox.Text = "" 
     Case Else 
      Me.TextBox.Text = Format(Val(Replace(Me.TextBox.Text, ",", ""))/100, "0.00") 
      Me.TextBox.SelectionStart = Len(Me.TextBox.Text) 
    End Select 
End Sub 

Dieses Stück Code verdächtig einfach zu mir. Für den Moment funktioniert es gut und macht genau das, was ich wollte. Vielleicht fehlt mir etwas, oder vielleicht war ich bei der Beschreibung meines Ziels nicht klar genug. Wenn Sie einen Fehler auf meiner Methode finden, zögern Sie nicht, darauf zu zeigen! Ich werde es sehr schätzen.

+0

Ich denke, das einzige, was darauf hinweisen würde, wäre, dass dies auch an den Dezimalpunkt des Systems anpassen wird Ersetze '", "' mit '" "wird nicht gelöscht Zum Beispiel ein amerikanisches System. Ansonsten sollte es wohl funktionieren. :) –

+0

Vielleicht ist das, warum es funktioniert ... Für einige Dinge, es ist gut, kein Amerikaner, eh eh eh ... Vielen Dank für Ihre Antwort :) – Pspl

+0

Nun, das einzige, was Sie tun müssen, ist ein zweites ersetzen und es sollte funktionieren: 'Ersetzen (Ersetzen (Me.TextBox.Text,", "," "),". "," ")' –

Verwandte Themen