cmddegi
Bekanntes Mitglied
Dieses Verhalten ist schon garnicht mehr so unkompliziert; es sind einige verschiedene Fälle zu unterscheiden. Am einfachsten zu lösen sind solche Sachen, indem du dir ein Zustandsdiagramm zeichnest, in dem sämtliche möglichen Zustände und die erlaubten Übergänge dazwischen eingezeichnet sind. Ein Zustand ist eine bestimmte Kombination der Statusvariablen. Von jedem Zustand gehen Pfeile zu den von dort aus erreichbaren Zuständen mit den zugehörigen Bedingungen. Am Besten mal im Internet schlau machen, wie sowas aussieht.
Im Anhang mal ein kommentierter Code von mir, der hoffentlich halbwegs fehlerfrei das tut, was du möchtest.
Im Anhang mal ein kommentierter Code von mir, der hoffentlich halbwegs fehlerfrei das tut, was du möchtest.
Code:
Public Class Form1
' m steht für Member der Klasse
Private mA As Double = 0 ' Operand A
Private mB As Double = 0 ' Operand B
Private mOp As String = "=" ' gespeicherter Operator
Private mLastWasEquals As Boolean = False ' letzer Operator war =
Private mDisplay As Double = 0 ' Wert im Display
Private mOverwrite As Boolean = True ' Display überschreiben
Private mCommaCounter As Integer = 0 ' aktuelle Nachkommastelle bei der Eingabe
Private Sub TextBoxDisplay_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBoxDisplay.KeyPress
Select Case e.KeyChar
Case "0" To "9" ' Zifferneingabe
Dim num As Integer = (Convert.ToInt16(e.KeyChar) - 48)
If mOverwrite Then ' Ziffer überschreibt Display
mDisplay = 0
mOverwrite = False
End If
If mCommaCounter = 0 Then
mDisplay = mDisplay * 10 + num
Else
mDisplay = mDisplay + (num / (10 ^ mCommaCounter))
mCommaCounter += 1
End If
Case ",", "." ' Komma
If mCommaCounter = 0 Then ' nur wenn noch kein Komma vorhanden
If mOverwrite Then ' Komma überschreibt Display
mDisplay = 0
mOverwrite = False
End If
mCommaCounter = 1
End If
Case "+", "-", "*", "/"
Compute(e.KeyChar)
Case "=", vbCr
Compute("=")
Case "c", "C"
mDisplay = 0
mA = 0
mB = 0
mOp = "="
mOverwrite = True
mCommaCounter = 0
mLastWasEquals = False
End Select
UpdateDisplay()
' Taste wurde verarbeitet
e.Handled = True
End Sub
Private Sub Compute(ByVal newOp As String)
' Wert aus Display bei = nur als B übernehmen, wenn voriges Ergebnis
' überschrieben wurde; sonst vorigen Operanden B beibehalten
'If (newOp = "=" And mOverwrite = False) Or newOp <> "=" Then
'mB = mDisplay
'End If
' zwei Rechenoperatoren hintereinander ohne Eingabe dazwischen verhindern
' aber Operator merken, damit man z.B. + nachträglich durch - ersetzen kann
If mOp <> "=" And newOp <> "=" And mOverwrite Then
mLastWasEquals = False
mOp = newOp
Return
End If
' Display nur nach B übernehmen, wenn letzter Operator nicht = war
' (damit Wiederholung der letzten Aktion durch mehrfaches = möglich ist)
' oder wenn eine neue Zahl eingegeben wurde
If Not mLastWasEquals Or (Not mOverwrite) Then
mB = mDisplay
End If
' ausrechnen und speichern
If Not (mLastWasEquals And newOp <> "=") Then
Select Case mOp
Case "+"
mA = mA + mB
Case "-"
mA = mA - mB
Case "*"
mA = mA * mB
Case "/"
If mDisplay <> 0 Then
mA = mA / mB
End If
Case "="
mA = mB
End Select
End If
' Ergebnis ins Display
mDisplay = mA
' Operator merken (wenn = dann alten behalten)
If newOp <> "=" Then
mOp = newOp ' neuen Operator merken
mLastWasEquals = False
Else
mLastWasEquals = True
End If
' nächste Ziffer überschreibt Display
mOverwrite = True
mCommaCounter = 0
End Sub
Private Sub UpdateDisplay()
' anzeigen aktualisieren
TextBoxDisplay.Text = mDisplay.ToString
TextBoxA.Text = mA.ToString
TextBoxB.Text = mB.ToString
TextBoxOp.Text = mOp
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
UpdateDisplay()
End Sub
End Class