Add a cancel button to input box VB - vb.net

I have made a simple calculator and I would like to know if you put in a string instead of a double and if you press close or not. The program is a simple calculator where the menu is a box with buttons for addition, subtraction, multiplication, and division. I would like it if you enter a string a messagebox pops up that tells you to enter a number and when you enter an empty message or click cancel it takes you back to the start of the program. Here is the code
Public Class CalcForm
Property num1 As Double = Nothing
Property num2 As Double = Nothing
Private Sub CalcForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Addition_Click(sender As Object, e As EventArgs) Handles Addition.Click
Getnum()
Dim Answer As Double = num1 + num2
MessageBox.Show("The answer is " & Answer, "Answer")
End Sub
Private Sub Subtraction_Click(sender As Object, e As EventArgs) Handles Subtraction.Click
Getnum()
Dim Answer As Double = num1 - num2
MessageBox.Show("The answer is " & Answer, "Answer")
End Sub
Private Sub Multiplication_Click(sender As Object, e As EventArgs) Handles Multiplication.Click
Getnum()
Dim Answer As Double = num1 * num2
MessageBox.Show("The answer is " & Answer, "Answer")
End Sub
Private Sub Division_Click(sender As Object, e As EventArgs) Handles Division.Click
Getnum()
Dim Answer As Double = num1 / num2
MessageBox.Show("The answer is " & Answer, "Answer")
End Sub
Private Sub Getnum()
num1 = InputBox("Enter your first number", "Number 1")
num2 = InputBox("Enter your second number", "Number 2")
End Sub
End Class
Also I don't care about the difference between an empty ok or a cancel. But since I use doubles do I have to make it a string then convert to an double? If I do, how do I detect if the string has letters and ask the user to re-enter their number?

Do you really need your message box?
If you follow Hans Passant's recommendations and start using TextBox, you could simply bind your variable properties and parse and format them.
Have a look at the example below, it is more lines of code but gets you an opportunity to look at binding parsing and formatting.
It is a simple form with your four buttons and 3 text boxes. User cannot "get out" of the TextBox value is not numeric. Should you go for this solution, I would recommend to set the TextBox property for the result to ReadOnly :)
Imports System.Math
Imports System.ComponentModel
Public Class Form1
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Private Sub NotifyPropertyChanged(ByVal info As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
End Sub
Private _num1 As Double
Property num1 As Double
Get
Return _num1
End Get
Set(value As Double)
If (value <> _num1) Then
_num1 = value
NotifyPropertyChanged("num1")
End If
End Set
End Property
Private _num2 As Double
Property num2 As Double
Get
Return _num2
End Get
Set(value As Double)
If (value <> _num2) Then
_num2 = value
NotifyPropertyChanged("num2")
End If
End Set
End Property
Private _Answer As Double
Property Answer As Double
Get
Return _Answer
End Get
Set(value As Double)
If (value <> _Answer) Then
_Answer = value
NotifyPropertyChanged("Answer")
End If
End Set
End Property
Private Sub CalcForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' TextBox for result
TextBox3.ReadOnly = True
Set_bindings()
End Sub
Private Sub Addition_Click(sender As Object, e As EventArgs) Handles Addition.Click
Answer = num1 + num2
End Sub
Private Sub Substraction_Click(sender As Object, e As EventArgs) Handles Substraction.Click
Answer = num1 - num2
End Sub
Private Sub Multiplication_Click(sender As Object, e As EventArgs) Handles Multiplication.Click
Answer = num1 * num2
End Sub
Private Sub Division_Click(sender As Object, e As EventArgs) Handles Division.Click
Answer = num1 / num2
End Sub
Private Sub Set_bindings()
Dim binH As Binding
TextBox1.DataBindings.Clear()
binH = New Binding("Text", Me, "num1", True, DataSourceUpdateMode.OnPropertyChanged)
AddHandler binH.Parse, AddressOf NumParser
AddHandler binH.Format, AddressOf NumFormatter
TextBox1.DataBindings.Add(binH)
TextBox2.DataBindings.Clear()
binH = New Binding("Text", Me, "num2", True, DataSourceUpdateMode.OnPropertyChanged)
AddHandler binH.Parse, AddressOf NumParser
AddHandler binH.Format, AddressOf NumFormatter
TextBox2.DataBindings.Add(binH)
TextBox3.DataBindings.Clear()
binH = New Binding("Text", Me, "Answer", True, DataSourceUpdateMode.Never)
AddHandler binH.Parse, AddressOf NumParser
AddHandler binH.Format, AddressOf NumFormatter
TextBox3.DataBindings.Add(binH)
End Sub
Private Sub NumParser(ByVal sender As Object, ByVal e As ConvertEventArgs)
If IsNumeric(e.Value) Then
e.Value = e.Value
End If
End Sub
Private Sub NumFormatter(ByVal sender As Object, ByVal e As ConvertEventArgs)
e.Value = FormatNum(e.Value)
End Sub
Private Function FormatNum(ByVal x As Double) As String
Dim sFormat As String
sFormat = ""
Select Case Abs(x)
Case 1 To 1000
sFormat = "##0.000"
Case Is > 10000
sFormat = "0.000E+00"
Case Is = 0
sFormat = "#0.0"
Case Is < 0.001
sFormat = "0.000E-00"
Case Is < 1
sFormat = "#0.0000"
End Select
FormatNum = Format(x, sFormat)
End Function
End Class

Related

Create a undo/redo textboxes algorithm in VB.Net

I would love to create a type algorithm Undo/Redo in VB.Net, first at least i want to make the undo.
if we have the example Textbox1.Text = a,b,c
then change to = a,b,c,e
then change to = a,b,c,f
when I click on undo I want to display (that is, the value before it. before after a,b, c, f, was a, b, c,e
a,b,c,e
and when I click once again I want to display
a,b,c
that is, an undo / redo algorithm of added values
I first created a global list.
Public Module Globals
Public Undo As New List(Of String)
End Module
if Textboxes value is not exists in the list, then I will add it.
Private Sub Button1(sender As Object, e As EventArgs) Handles Button1.Click
If Undo IsNot TextBox1.Text Then
Undo.Add(TextBox1.Text)
End If
End Sub
hey well here's the tricky part
Private Sub Undo_Click(sender As Object, e As EventArgs) Handles Undo.Click
Dim i as integer = Undo.Count
While TextBox1.Text IsNot Undo(i)
TextBox1.Text = Undo(i)
End While
End Sub
For i As Integer = Undo.Count To 0 Step -1
TextBox1.Text = Undo(i)
Next
unfortunately no such loop works in this case.
Try this:
Private Undos As List(Of String) = New List(Of String)()
Private AddUndo As Boolean = True
Private Sub textBox1_TextChanged(ByVal sender As Object, ByVal e As EventArgs)
If AddUndo = True Then
Undos.Add(textBox1.Text)
End If
End Sub
Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs)
If Undos.Count <> 0 Then
AddUndo = False
If Undos.Count > 1 Then
textBox1.Text = Undos(Undos.Count - 2)
Undos.RemoveAt(Undos.Count - 1)
Else
textBox1.Text = ""
Undos.RemoveAt(0)
End If
AddUndo = True
End If
End Sub

Cant get value from VB class

I am trying to make a simple, class based calculator in Visual Basic, but when I press the buttons (Add) (Multiply) it shows 0 as the value in the textbox.
Here is my code:
FORM 2:
Public Class Form2
Dim Class2 As part2Class = New part2Class()
Dim Class2b As part2ClassB = New part2ClassB()
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Num1 As Integer = CType(TextBox1.Text, Integer)
Dim Num2 As Integer = CType(TextBox2.Text, Integer)
MessageBox.Show(Class2.Calculate().ToString())
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim Num1 As Integer = CType(TextBox1.Text, Integer)
Dim Num2 As Integer = CType(TextBox2.Text, Integer)
MessageBox.Show(Class2b.Calculate())
End Sub
End Class
part2Class CLASS
Public Class part2Class
Public Property Num1
Public Property Num2
Public Overridable Function Calculate() As Integer
Return Num1 + Num2
End Function
End Class
Part2ClassB
Public Class part2ClassB
Inherits part2Class
Public Overrides Function Calculate() As Integer
Return Num1 * Num2
End Function
End Class
When I put values in the textbox and press ADD/MULIPLY it shows 0 as the value.
You are not assigning the values to the properties of your classes. Try this:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim Num1 As Integer = CType(TextBox1.Text, Integer)
Dim Num2 As Integer = CType(TextBox2.Text, Integer)
Class2b.Num1=Num1
Class2b.Num2=Num2
MessageBox.Show(Class2b.Calculate())
End Sub
If CType fails you will crash your program. I changed it to TryParse which sets the variable in the second parameter (in this case a property of the class) and returns True or False. The AndAlso stops as soon as it reaches a False and proceeds to the Else part of the If
You need to declare your properties with a datatype in your class. See my comment about Option Strict.
Public Class part2Class
Public Property Num1 As Integer
Public Property Num2 As Integer
Public Overridable Function Calculate() As Integer
Return Num1 + Num2
End Function
End Class
Public Class part2ClassB
Inherits part2Class
Public Overrides Function Calculate() As Integer
Return Num1 * Num2
End Function
End Class
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim Class2 As part2Class = New part2Class()
Dim message As String
If Integer.TryParse(TextBox1.Text, Class2.Num1) AndAlso Integer.TryParse(TextBox2.Text, Class2.Num2) Then
message = Class2.Calculate().ToString
Else
message = "Please enter a number in both text boxes."
End If
MessageBox.Show(message)
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim Class2b As part2ClassB = New part2ClassB()
Dim message As String
If Integer.TryParse(TextBox1.Text, Class2b.Num1) AndAlso Integer.TryParse(TextBox2.Text, Class2b.Num2) Then
message = Class2b.Calculate().ToString
Else
message = "Please enter a number in both text boxes."
End If
MessageBox.Show(message)
End Sub

How change Compare Multiple Textbox

I have 2 codes to change the color to Textbox, and unfortunately none of them work. What's wrong here? Why the code is not good. Every time I try the code, not worked, The first code changes the color to Textbox if there is a value between 1 and 7, and the second changes the value in ascending order from the lowest to the highest and assigns a corresponding color. Please tell me if these 2 codes are written correctly, or there is a write error.
Code 1: Image: http://www.imagebam.com/image/5ac5ee1073004874
Public Class TextBoxColors
Private ColorTable As Dictionary(Of String, Color) = New Dictionary(Of String, Color)()
Public Sub New()
ColorTable.Add("1", Color.Red)
ColorTable.Add("2", Color.Aqua)
ColorTable.Add("3", Color.Chocolate)
ColorTable.Add("4", Color.BlanchedAlmond)
ColorTable.Add("5", Color.BurlyWood)
ColorTable.Add("6", Color.BlueViolet)
ColorTable.Add("7", Color.DarkBlue)
End Sub
Public Function GetColor(ColorMap As String) As Color
Return If(ColorTable.Keys.Contains(ColorMap), ColorTable(ColorMap), Color.White)
End Function
End Class
Private txtColor As TextBoxColors = New TextBoxColors()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each txtDraw As TextBox In Me.Controls.OfType(Of TextBox).Where(Function(txt) txt.Name.StartsWith("txtDraw"))
AddHandler txtDraw.TextChanged,
Sub()
If Not String.IsNullOrEmpty(txtDraw.Text) Then
txtDraw.BackColor = txtColor.GetColor(txtDraw.Text)
End If
End Sub
Next
End Sub
Code 2: This 2nd code must be changed based on my text box, which starts with SumtxtDraw
- Image: http://www.imagebam.com/image/92a4091073004904
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
FillColorList()
End Sub
Private Sub ColorTextBoxes()
FillTextBoxList(16, 23)
Dim SortedList As List(Of TextBox) = SortList()
Dim index As Integer
For Each txt As TextBox In SortedList
txt.BackColor = lstColor(index)
index += 1
Next
End Sub
Private Sub FillColorList()
lstColor.Add(Color.Red) 'for lowest number
lstColor.Add(Color.BlanchedAlmond)
lstColor.Add(Color.PaleGreen)
lstColor.Add(Color.Chartreuse)
lstColor.Add(Color.CadetBlue)
lstColor.Add(Color.Orange)
lstColor.Add(Color.DarkMagenta)
lstColor.Add(Color.Violet) 'for highest number
End Sub
Private Sub FillTextBoxList(StartNumber As Integer, EndNumber As Integer)
lstTextBox.Clear()
For suffix = StartNumber To EndNumber
lstTextBox.Add(DirectCast(Controls("TextBox" & suffix.ToString), TextBox))
Next
End Sub
Private Function SortList() As List(Of TextBox)
Dim orderedList = From txt In lstTextBox Order By CInt(txt.Text) Descending Select txt '$"{scorer.Score} - {scorer.Name}"
Dim SortedList As List(Of TextBox) = orderedList.ToList
Return SortedList
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ColorTextBoxes()
End Sub

Random delay in seconds from numericupdown in VB.Net

I have a desktop winforms app code:
Sub Delay(ByVal dblSecs As Double)
Const OneSec As Double = 1.0# / (1440.0# * 60.0#)
Dim dblWaitTil As Date
Now.AddSeconds(OneSec)
dblWaitTil = Now.AddSeconds(OneSec).AddSeconds(dblSecs)
Do Until Now > dblWaitTil
Application.DoEvents()
Loop
End Sub
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
Webbrowser1.Navigate(TextBox1.Text)
Delay(Val(DelayText.Text))
end sub
What I need is to set max. delay, same from textbox by entering seconds.
I need this to be random delay number so Im stacking here, thanks for correcting my code.
Also If its possible to make it in NumericUpDown, as i found some topics which says textbox text property is different as NumericUpDown but i like it more.
You could use an inbetween class which does most of the work for you
This class would take the WebBrowser, attach to some events of it, and would refresh periodically (depending on MinimumWait / MaximumWait)
As it is using threading, it also checks if the usercontrol needs to be invoked to Refresh it and when yes, invokes the custom refresh delegate
Public Class Refresher
Protected Delegate Sub RefreshNavigationDelegate(browser As WebBrowser)
Protected Sub RefreshNavigation(browser As WebBrowser)
If browser.InvokeRequired Then
browser.Invoke(New RefreshNavigationDelegate(AddressOf RefreshNavigation), browser)
Return
End If
browser.Refresh(WebBrowserRefreshOption.Completely)
End Sub
Private _isBusy As Boolean = False
Public Property IsBusy As Boolean
Get
Return _isBusy
End Get
Protected Set(value As Boolean)
If _isBusy = value Then
Return
End If
_isBusy = value
End Set
End Property
Public Property MinimumWait As Integer = 2000
Public Property MaximumWait As Integer = 10000
Private refreshThread As Thread = Nothing
Private _browser As WebBrowser
Public Property Browser As WebBrowser
Get
Return _browser
End Get
Set(value As WebBrowser)
If Object.Equals(_browser, value) Then
Return
End If
StopRefresh()
If _browser IsNot Nothing Then
RemoveHandler Browser.DocumentCompleted, AddressOf DocumentComplete
RemoveHandler Browser.Navigating, AddressOf Navigating
End If
_browser = value
If _browser IsNot Nothing Then
AddHandler Browser.DocumentCompleted, AddressOf DocumentComplete
AddHandler Browser.Navigating, AddressOf Navigating
AddHandler Browser.ProgressChanged, AddressOf ProgressChanged
End If
StartRefresh()
End Set
End Property
Protected Sub ProgressChanged(sender As Object, e As WebBrowserProgressChangedEventArgs)
IsBusy = e.CurrentProgress > 0 AndAlso e.CurrentProgress < e.MaximumProgress
End Sub
Protected Sub DocumentComplete(sender As Object, e As WebBrowserDocumentCompletedEventArgs)
IsBusy = False
End Sub
Protected Sub Navigating(sender As Object, e As WebBrowserNavigatingEventArgs)
IsBusy = True
End Sub
Public Sub StartRefresh()
If refreshThread IsNot Nothing Then
Return
End If
refreshThread = New Thread(AddressOf DoRandomRefreshes)
refreshThread.Start()
End Sub
Public Sub StopRefresh()
If refreshThread Is Nothing Then
Return
End If
refreshThread.Abort()
refreshThread = Nothing
End Sub
Protected Overridable Sub DoRandomRefreshes()
Dim randomGenerator As New Random()
While Not refreshThread.ThreadState = ThreadState.AbortRequested
Dim newTimeout As Integer = MinimumWait + randomGenerator.Next(MaximumWait - MinimumWait)
Thread.Sleep(newTimeout)
If Not IsBusy Then
RefreshNavigation(Browser)
End If
End While
End Sub
Public Sub New()
End Sub
End Class
You could then use it in your form as such:
Public Class Form1
Dim myRefresher As Refresher = New Refresher()
Private Sub tsbGo_Click(sender As Object, e As EventArgs) Handles tsbGo.Click
WebBrowser1.Navigate(txtUrl.Text)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
myRefresher.Browser = WebBrowser1
End Sub
Private Sub txtMin_TextChanged(sender As Object, e As EventArgs) Handles txtMin.TextChanged
Dim int As Integer = 0
If Integer.TryParse(txtMin.Text, int) Then
myRefresher.MinimumWait = int
End If
End Sub
Private Sub txtMax_TextChanged(sender As Object, e As EventArgs) Handles txtMax.TextChanged
Dim int As Integer = 0
If Integer.TryParse(txtMax.Text, int) Then
myRefresher.MaximumWait = int
End If
End Sub
End Class

giving calculator input from keyboard keys without pressing calculator buttons

I created a VB.net calculator application.It works fine but say I want to add 5+7.Then as my application works I can press 5 from the keyboard as I gave the text of button with digit 5 as &5 but then if I press + from the keyboard it doesn't work.I have to press the + button in the calculator.
I think that's because my add button is designed to handle click event as btn_add_Click.Is there a way I can make this application to work so that without pressing the buttons in the calculator I can press the keys in keyboard and do the computation.Here's my code:
Imports System.Math
Public Class Form1
Private isFirstExist As Boolean
Private inputOperator As String
Private secondNum As Decimal
Private firstNum As Decimal
Private Sub TextBox1_TextChanged(sender As System.Object, e As System.EventArgs) Handles txtCalc.TextChanged
End Sub
Private Sub btn_zero_Click(sender As System.Object, e As System.EventArgs) Handles btn_zero.Click
removeFrontZero(0)
End Sub
Private Sub btn_one_Click(sender As System.Object, e As System.EventArgs) Handles btn_one.Click
removeFrontZero(1)
End Sub
Private Sub btn_two_Click(sender As System.Object, e As System.EventArgs) Handles btn_two.Click
removeFrontZero(2)
End Sub
Private Sub btn_clear_Click(sender As System.Object, e As System.EventArgs) Handles btn_clear.Click
txtCalc.Clear()
txtCalc.Text = "0"
End Sub
'Remove zero which is at the start
Public Sub removeFrontZero(ByVal digit As Integer)
If txtCalc.Text = "0" Then
txtCalc.Text = CStr(digit)
Else
txtCalc.Text &= digit
End If
End Sub
Private Sub btn_add_Click(sender As System.Object, e As System.EventArgs) Handles btn_add.Click
inputOperator = "+"
isFirst()
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
isFirstExist = False
End Sub
Private Sub btn_equal_Click(sender As System.Object, e As System.EventArgs) Handles btn_equal.Click
If isFirstExist Then
secondNum = CType(txtCalc.Text, Decimal)
End If
'Calculating the result
Dim result As Decimal = calculate(firstNum, secondNum, inputOperator)
txtCalc.Text = result.ToString()
isFirstExist = False
End Sub
Private Function calculate(ByVal num1 As Decimal, ByVal num2 As Decimal, ByVal inputOp As String) As Decimal
Dim output As Decimal
firstNum = num1
secondNum = num2
Select Case inputOp
Case "+"
output = num1 + num2
Case "-"
output = num1 - num2
Case "/"
Dim value As Decimal
Try
isFirst()
value = (num1 / num2)
Catch ex As DivideByZeroException
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK)
End Try
output = value
Case "*"
output = num1 * num2
Case "Mod"
output = (num1 Mod num2)
Case "^"
output = CDec(Math.Pow(num1, num2))
End Select
Return output
End Function
Private Sub isFirst()
If isFirstExist = False Then
firstNum = CType(txtCalc.Text, Decimal)
isFirstExist = True
txtCalc.Text = "0"
End If
End Sub
Assuming you're using the textbox to hold the users input, in the Textchanged or even KeyPressed handler trap the operator keys and run the function instead of displaying the operator.
Something like this:
Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtCalc.KeyPress
If e.KeyChar = "+"c Then
inputOperator = "+"
isFirst()
e.Handled = True
End If
End Sub
To display the operator set handled to false.