#.net #vb.net #visual-studio #winforms
#.net #vb.net #visual-studio #winforms
Вопрос:
Я использую Microsoft Visual Studio professional 2019 версии 16.6.2.
Я создал простой калькулятор с использованием Windows forms. Предполагается, что калькулятор позволяет пользователю нажимать на цифровые кнопки, а также кнопки для различных операторов, а затем отображать результат в текстовом поле после нажатия кнопки = . Калькулятор также имеет десятичную точку, чтобы помочь вычислить десятичное число.
Однако я получаю сообщение об ошибке «преобразование из строки в десятичный тип недопустимо» всякий раз, когда я пытаюсь вычислить десятичные числа.
Я все еще студент и не очень разбираюсь в продвинутом программировании. Если возможно, пожалуйста, постарайтесь, чтобы ваши предложения были как можно более простыми.
Public Class Form1
Dim firstNum As Decimal
Dim secondNum As Decimal
Dim operations As Integer
Dim operator_Selector As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles btn2.Click
If txtDisplay.Text <> "0" Then
txtDisplay.Text = "2"
Else
txtDisplay.Text = "2"
End If
End Sub
Private Sub btn1_Click(sender As Object, e As EventArgs) Handles btn1.Click
If txtDisplay.Text <> "0" Then
txtDisplay.Text = "1"
Else
txtDisplay.Text = "1"
End If
End Sub
Private Sub btn3_Click(sender As Object, e As EventArgs) Handles btn3.Click
If txtDisplay.Text <> "0" Then
txtDisplay.Text = "3"
Else
txtDisplay.Text = "3"
End If
End Sub
Private Sub btn4_Click(sender As Object, e As EventArgs) Handles btn4.Click
If txtDisplay.Text <> "0" Then
txtDisplay.Text = "4"
Else
txtDisplay.Text = "4"
End If
End Sub
Private Sub btn5_Click(sender As Object, e As EventArgs) Handles btn5.Click
If txtDisplay.Text <> "0" Then
txtDisplay.Text = "5"
Else
txtDisplay.Text = "5"
End If
End Sub
Private Sub btn6_Click(sender As Object, e As EventArgs) Handles btn6.Click
If txtDisplay.Text <> "0" Then
txtDisplay.Text = "6"
Else
txtDisplay.Text = "6"
End If
End Sub
Private Sub btn7_Click(sender As Object, e As EventArgs) Handles btn7.Click
If txtDisplay.Text <> "0" Then
txtDisplay.Text = "7"
Else
txtDisplay.Text = "7"
End If
End Sub
Private Sub btn8_Click(sender As Object, e As EventArgs) Handles btn8.Click
If txtDisplay.Text <> "0" Then
txtDisplay.Text = "8"
Else
txtDisplay.Text = "8"
End If
End Sub
Private Sub btn9_Click(sender As Object, e As EventArgs) Handles btn9.Click
If txtDisplay.Text <> "0" Then
txtDisplay.Text = "9"
Else
txtDisplay.Text = "9"
End If
End Sub
Private Sub btn0_Click(sender As Object, e As EventArgs) Handles btn0.Click
If txtDisplay.Text <> "0" Then
txtDisplay.Text = "0"
End If
End Sub
Private Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnClear.Click
txtDisplay.Text = "0"
End Sub
Private Sub btnPoint_Click(sender As Object, e As EventArgs) Handles btnPoint.Click
If Not (txtDisplay.Text.Contains(".")) Then
txtDisplay.Text = "."
End If
End Sub
Private Sub btnadd_Click(sender As Object, e As EventArgs) Handles btnadd.Click
firstNum = txtDisplay.Text
txtDisplay.Text = "0"
operator_Selector = True
operations = 1
End Sub
Private Sub btnEqual_Click(sender As Object, e As EventArgs) Handles btnEqual.Click
If operator_Selector = True Then
secondNum = txtDisplay.Text
End If
If operations = 1 Then
txtDisplay.Text = firstNum secondNum
End If
If operations = 2 Then
txtDisplay.Text = firstNum - secondNum
End If
If operations = 3 Then
secondNum = txtDisplay.Text
txtDisplay.Text = firstNum * secondNum
End If
If operations = 4 Then
If secondNum = 0 Then
txtDisplay.Text = "ERROR! CANNOT DIVIDE BY 0"
Else
txtDisplay.Text = firstNum / secondNum
End If
End If
operator_Selector = False
End Sub
Private Sub btnSubtract_Click(sender As Object, e As EventArgs) Handles btnSubtract.Click
firstNum = txtDisplay.Text
txtDisplay.Text = "0"
operator_Selector = True
operations = 2
End Sub
Private Sub btnMultiply_Click(sender As Object, e As EventArgs) Handles btnMultiply.Click
firstNum = txtDisplay.Text
txtDisplay.Text = "0"
operator_Selector = True
operations = 3
End Sub
Private Sub btnDivide_Click(sender As Object, e As EventArgs) Handles btnDivide.Click
firstNum = txtDisplay.Text
txtDisplay.Text = "0"
operations = 4
operator_Selector = True
End Sub
End Class
Комментарии:
1. Вы можете остановить отладчик в точке исключения и посмотреть, какое значение пытается преобразовать. И если вы включите
OPTION STRICT
, вы внезапно увидите, что выполняете неявные преобразования в десятичный тип, не выполняя никакой проверки. Имейте в виду, что, учитывая способ, которым вы это создали, нет необходимости фактически использовать значение в текстовом поле для выполнения вычисления, вы можете хранить числа внутри2. Вы работаете со строками. Такие вещи, как
secondNum = 0
не будут работать, посколькуsecondNum
это строка. Вы должны сначала преобразовать их вInteger
илиDecimal
, прежде чем работать с ними, как если бы они были фактическими числами.
Ответ №1:
Вы объявили firstNum
и secondNum
как Decimal
(числа), что правильно.
Text
Свойство текстовых полей — a String
.
.NET не хочет автоматически преобразовывать String
значение в a Decimal
, потому что, вообще говоря, это преобразование неверно определено. Это зависит от вашей культуры: например, какой у вас разделитель тысяч? Это может легко завершиться ошибкой, если строка не представляет число, например "ABC"
. Также может произойти сбой или потеря точности, если строка содержит больше цифр, чем Decimal
может хранить.
Таким образом, в основном строки типа firstNum = txtDisplay.Text
и secondNum = txtDisplay.Text
присваивают String
значение Decimal
переменной, и это то, что язык запрещает.
Вам нужно будет использовать функцию, которая выполняет это преобразование за вас.
Поскольку вы используете VB.NET вы можете использовать CDec
(расшифровывается как Convert to Decimal) , который более или менее преобразует что-либо в a Decimal
.
firstNum = CDec(txtDisplay.Text)
CDec
специфично для VB.NET хотя. Стандартная функция из библиотеки базовых классов (которую вы могли бы использовать, например, в C #) Decimal.Parse
— это преобразование строки в десятичное число. Если вы посмотрите на документацию, вы обнаружите, что она может принимать дополнительные параметры, которые управляют тем, как выполняется синтаксический анализ (язык, параметры номера и т. Д.)
firstNum = Decimal.Parse(txtDisplay.Text)
В качестве дополнительного совета вы могли бы действительно уменьшить количество обработчиков кликов, если бы вы поместили число, которое они представляют, в свойство control Tag
.
Первым параметром sender
в обработчике щелчка является элемент управления, на который был нажат. Итак, предполагая, что вы помещаете значения "0"
, "1"
, … в Tag
свойство каждой кнопки, вы можете повторно использовать один и тот же обработчик щелчков для всех из них, выполнив что-то вроде txtDisplay.Text = sender.Tag
.