Textbox only converter - vb.net

I am making a temperature converter in vb.net for my assignment. I know the conversion method and so on.. but the problem is, I need to only use two textboxes. One for Celsius and one for farenheit. Whenever I update the textbox for celsius, the changes on textbox should also happen, and when I change the value for farenheit, the celsius textbox should also change depending on the value for farenheit. What method should I do?
This is the current one im working on..
Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
If TextBox1.Focus() Then
TextBox2.Clear()
TextBox2.Text = (TextBox1.Text - 32) / 1.8
ElseIf TextBox2.Focus() Then
TextBox1.Clear()
TextBox1.Text = (TextBox2.Text * 1.8) + 32
End If
End Sub
End Class

Thanks for posting some code. This is the way I'd do it (after wiring up TextChanged event handlers for both text boxes):
Private DegreesCChanging As Boolean = False
Private DegreesFChanging As Boolean = False
Private Sub DegreesF_TextChanged(sender As Object, e As EventArgs) Handles DegreesF.TextChanged
If Not DegreesFChanging Then
Dim Temperature As Double
DegreesCChanging = True
If Double.TryParse(DegreesF.Text, Temperature ) Then
DegreesC.Text = ((Temperature - 32.0) / 9.0 * 5.0).ToString("0.##")
Else
DegreesC.Text = String.Empty
End If
DegreesCChanging = False
End If
End Sub
Private Sub DegreesC_TextChanged(sender As Object, e As EventArgs) Handles DegreesC.TextChanged
If Not DegreesCChanging Then
Dim Temperature As Double
DegreesFChanging = True
If Double.TryParse(DegreesC.Text, Temperature ) Then
DegreesF.Text = (Temperature / 5.0 * 9.0 + 32.0).ToString("0.##")
Else
DegreesF.Text = String.Empty
End If
DegreesFChanging = False
End If
End Sub
There are a few things to note.
I'm using the TextChanged event - as soon as the user types
something into either text box, the world starts changing
I use double.TryParse to convert the number to a string. If I can't figure out what's going on (i.e., the TryParse call returns False), I stick an empty string in the other text box. It works quite well.
When the user types something into a text box, it causes a TextChanged event that forces new text into the other text box - which will result in a TextChanged event for that control. I use two Boolean flags to prevent this.
I use a custom numeric format string on my ToString calls to limit
the precision to two decimal places.

Related

Crash of application while debugging when Textbox is empty

I'd like to create a Textbox, whose text changes color dynamically from black to red when a value larger than a number is typed, and vice versa. I managed to do this but when I erase all the content of the textbox, my debugging application crashes with the error System.InvalidCastException: 'Conversion from string "" to type 'Double' is not valid.' Here is the code I'm using:
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
If CDbl(TextBox1.Text) > CDbl(Label2.Text) Then
TextBox1.ForeColor = Color.Red
End If
If CDbl(TextBox1.Text) = CDbl(Label2.Text) Then
TextBox1.ForeColor = Color.Black
End If
If CDbl(TextBox1.Text) < CDbl(Label2.Text) Then
TextBox1.ForeColor = Color.Black
End If
If TextBox1.Text = "" Then
TextBox1.ForeColor = Color.Black
End If
End Sub
Which feature do I have to add in order to prevent the crashing of my application? Thanks in advance. Best regards.
Your code has multiple issues that may require attention.
The VB casting functions like CInt, CDbl etc. will throw an exception if casting fails. An empty value does not represent a numerical value, so it will fail. A solution might be to check for empty string values first.
You also might want to use an If ... ElseIf ... ElseIf ... ElseIf ... EndIf construct to avoid execution of subsequent if-blocks once you executed a matching if-block.
But then the code would crash if you would type a non-numeric value, like "A"...
So I would propose to use the Double.TryParse method instead of CDbl here.
Also notice that you normally want to use black as the default foreground color, but only want to switch to red if the value of the textbox is larger than the value of the label. Why not just express that literally in code?
So here are my two cents, using a variable NewForeColor that is initially set to Color.Black. It is then only set to Color.Red if both the textbox and the label hold a numerical value and the textbox value is larger than the label value. Eventually the textbox's foreground color is set to the value of the NewForeColor variable:
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
Dim NewForeColor As Color = Color.Black
Dim TextBox1Value As Double
Dim Label2Value As Double
If Double.TryParse(TextBox1.Text, TextBox1Value) AndAlso Double.TryParse(Label2.Text, Label2Value) Then
If TextBox1Value > Label2Value Then
NewForeColor = Color.Red
End If
End If
TextBox1.ForeColor = NewForeColor
End Sub

vb.net textbox not displaying text or colors

I have many applications that reliably display data and colors in text boxes. I copied one working program to make a new application. There are about 10 text boxes that I use for data displays. Some are working - and some are not. Here are 2 samples - the Switch code works in many programs - but here it will put the word "ON" in the box but no color, and then when the switch is off - no change to the textbox. The code seems not to care between the .AppendText or the .text = variable control. I have tried changing the properties of the text box to public but no luck. I have tried adding the .show object, and verified the .visible attribute in the properties view. A similar problem is with the DistanceUnitsOut and the NextImageDistanceOut - I can step through the code and see the values, but the displayed data does not change! I have tried changing the definition of the display to public - no joy!
SwitchStatusBox.clear
SwitchStatusBox.AppendText(SwitchStatusIn)
If SwitchStatusIn = "OFF" Then
SwitchStatusBox.BackColor.Equals(Color.Red)
SwitchStatusBox.Show()
Switch_Is_On = False
Else
SwitchStatusBox.BackColor = Color.Green
SwitchStatusBox.Show()
Switch_Is_On = True
End If
If dDistance > 1.0 Then
'show distance in Miles
DistanceUnitsOut.Clear()
DistanceUnitsOut.Text = "MI"
NextImageDistanceOut.Clear()
NextImageDistanceOut.Text = CType(dDistance, String)
Else
NextImageDistanceOut.Clear()
NextImageDistanceOut.Text = CType(dDistanceFT, String)
DistanceUnitsOut.Clear()
DistanceUnitsOut.Text = "FT"
End If
Private Sub NextImageDistanceOut_TextChanged(sender As Object, e As EventArgs) Handles
NextImageDistanceOut.TextChanged
End Sub
Private Sub DistanceUnitsOut_TextChanged(sender As Object, e As EventArgs) Handles
DistanceUnitsOut.TextChanged
End Sub
To see how the .Equals function works...
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim a = TextBox1.BackColor.Equals(Color.Red)
Debug.Print(a.ToString)
End Sub
In my test app this prints False in the Immediate window.
The answer is that some time ago I began using <variablename_OUT> followed by the TEXT = as in :
NextImageDistanceOut.Text = CType(dDistanceFT, String)
what worked was:
NextImageDistanceOut.Appendtext(CStr(dDistanceFT))
I still don't understand why the first did not work - Both require a previous
NextImageDistanceOut.Clear

How can I make it so a TextBox will dynamically adjust the input as a currency format?

This app I'm designing has a TextBox named txtValue with the properties MaxLength set to 14 and TextAlign set to Right. I want txtValue to only accept currency, and dynamically format the input so the user doesn't need to add commas, only one period.
I managed to make it so txtValue will only accept numbers and one dot in the event txtValue_KeyPress.
txtValue_LostFocus will convert the input into currency format.
Here's my code so far:
Private Sub txtValue_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtValue.KeyPress
'Allows only one dot
If (e.KeyChar.ToString = ".") And (txtValue.Text.Contains(e.KeyChar.ToString)) Then
e.Handled = True
Exit Sub
End If
'Allows only 0 to 9 and dot (once)
If (e.KeyChar.ToString < "0" OrElse e.KeyChar.ToString > "9") _
AndAlso e.KeyChar <> ControlChars.Back _
AndAlso e.KeyChar.ToString <> "." Then
e.Handled = True
End If
End Sub
Private Sub txtValue_LostFocus(sender As Object, e As EventArgs) Handles txtValue.LostFocus
txtValue.Text = Format(Val(txtValue.Text), "000,000,000.00")
End Sub
I expect the input -q1w23456789012....34 to return the output 123,456,789,012.34, but the actual output after it loses focus is 123,456,789,012.30
This seems like an easy fix, like setting MaxLength to 15, but then if I don't type a period, it'll allow me to type 15 numbers and I only want up to 12 plus 2 after the period.
I expect the input -q1w234....5678 to return the output 1,234.56, but the actual output after it loses focus is 000,000,001,234.56
This seems like a more complex fix, because I don't want to use the LostFocus event to validate what I type. I want the KeyPress event to handle the input and dynamically format what I type.
In this case:
The input 1 would have the output 1.00
The input 123.4 would have the output 123.40
The input 1234.567 would have the output 1,234.56
All of this without needing the LostFocus event, but right now I'm using the LostFocus event because that's all my very limited knowledge allows me to do.
UPDATE
Alright I'm now using the Leave event, but then again I was only using LostFocus as a placeholder because in the end I want the TextBox to adjust what the user types as they type.
An alternative way to handle. For details on formating numbers for display try MS docs https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings or https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings
Private err As New ErrorProvider()
Private d As Decimal 'In case you want to use the value as a number somewhere else
Private Sub TextBox17_Validating(sender As Object, e As CancelEventArgs) Handles TextBox17.Validating
If Not Decimal.TryParse(TextBox17.Text, d) Then
e.Cancel = True
err.SetError(TextBox17, "This text box must contain a number.")
Else
err.Clear()
End If
End Sub
Private Sub TextBox17_Validated(sender As Object, e As EventArgs) Handles TextBox17.Validated
TextBox17.Text = d.ToString("C")
End Sub

Case Statement not working with String Literals

Hi all I am trying to learn VB and am having trouble with some code I am using. I would like my program to output a specific number based on if a check box is checked using case statements but my code is not working.
Public Class frmBTPW
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btncalc.Click
Dim dblhdr As Double
Dim dblfdr As Double
Dim dbltdr As Double
dblhdr = 24
dblfdr = 35
dbltdr = 50
Select Case "Power Wash Rental"
Case "Half Day Rental"
If chkhd.Checked = True Then
txtrc.Text = "poop"
End If
Case "Full Day Rental"
If chkFD.Checked = True Then
txtrc.Text = dblfdr
End If
End Select
End Sub
Private Function Button1_Click() As CheckBox
Throw New NotImplementedException
End Function
End Class
Help would be greatly appreciated.My code isn't outputting anything in the text-box.
Beyond case statements, respectfully I think you should read up on the distinction between a literal value and a variable. "Power Wash Rental" is nothing more than a series of characters, AKA a string: (In this case "P" followed by "o" etc.) Likewise, "Half Day Rental" is a series of characters, "H" followed by "a" etc.)
"Power Wash Rental" is a literal string. So is ""Half Day Rental" and of course they will never match.
Whereas:
Dim A as string
A = TextBox1.text
Now, A is a variable. It is a string which contains whatever series of characters (text) is typed into the textbox.
This is a simple way to do it.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
chkhd.tag = 24 ' store values in the check boxes
chkfd.tag = 35 ' using the tag property
chktd.tag = 50 ' and later add up the values
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles btncalc.Click
dim total as double = 0
total += IF(chkhd.checked, cdbl(chkhd.tag), 0)
total += IF(chkfd.checked, cdbl(chkfd.tag), 0)
total += IF(chktd.checked, cdbl(chktd.tag), 0)
msgbox(total)
End Sub
However, I think you might want radio buttons instead of checkboxes.
Checkboxes can all be checked. Radio buttons can only have one at a time.
This solution allows you to keep your price with the checkbox -- you could do this in the form designer instead of form load.
I would recommend reading up on Case Statements. Currently you will never get anywhere as your using a string to what, nothing. You also do not need a case for this... Also if the first condition is true and the last one is as well, the last one win's for setting the text, didn't know if you had this there for a reason or not?
If chkhd.Checked = True Then
txtrc.Text = "poop"
End If
If chkFD.Checked = True Then
txtrc.Text = dblfdr
End If
As others have stated your Case statement isn't working because you are using string literals to compare "Power Wash Rental" to "Half Day Rental" which will always be false. Plutonix was also correct in saying that a ComboBox for the rental duration should be used. The only reason not to be is if you were calculating cumulative rental days/amounts; however in that situation you should be using some sort of NumericUpDown for your multiplier against a time duration.
Here is an example that should help you get started. You could make the structure into a type of keyed collection or make it a wrapper class for a dictionary object which would make be easier to use in code. The following may not be exactly plug-and-play with your project, however it should help give you some ideas on how to handle the situation.
Option Strict On
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.ComboBox1.Items.AddRange({PowerWashRentals.halfDayText, PowerWashRentals.FullDayText, PowerWashRentals.TwoDayText})
AddHandler ComboBox1.SelectedValueChanged, AddressOf Me.ComboBox1_SelectedChanged
End Sub
Private Sub ComboBox1_SelectedChanged(sender As Object, e As EventArgs)
Dim cBox As ComboBox = DirectCast(sender, ComboBox)
Select Case cBox.SelectedItem.ToString
Case PowerWashRentals.halfDayText
Label1.Text = PowerWashRentals.HalfDayPrice.ToString
Case PowerWashRentals.FullDayText
Label1.Text = PowerWashRentals.FullDayPrice.ToString
Case PowerWashRentals.TwoDayText
Label1.Text = PowerWashRentals.TwoDayPrice.ToString
End Select
End Sub
End Class
Public Structure PowerWashRentals
Public Const HalfDayPrice As Double = 24
Public Const FullDayPrice As Double = 35
Public Const TwoDayPrice As Double = 50
Public Const halfDayText As String = "Half Day Rental"
Public Const FullDayText As String = "Full Day Rental"
Public Const TwoDayText As String = "Two Day Rental"
End Structure

Search ListBox elements in VB.Net

I'm migrating an application from VB6 to VB.Net and I found a change in the behavior of the ListBox and I'm not sure of how to make it equal to VB6.
The problem is this:
In the VB6 app, when the ListBox is focused and I type into it, the list selects the element that matches what I type. e.g. If the list contains a list of countries and I type "ita", "Italy" will be selected in the listbox.
The problem is that with the .Net version of the control if I type "ita" it will select the first element that starts with i, then the first element that starts with "t" and finally the first element that starts with "a".
So, any idea on how to get the original behavior? (I'm thinking in some property that I'm not seeing by some reason or something like that)
I really don't want to write an event handler for this (which btw, wouldn't be trivial).
Thanks a lot!
I shared willw's frustration. This is what I came up with. Add a class called ListBoxTypeAhead to your project and include this code. Then use this class as a control on your form. It traps keyboard input and moves the selected item they way the old VB6 listbox did. You can take out the timer if you wish. It mimics the behavior of keyboard input in Windows explorer.
Public Class ListBoxTypeAhead
Inherits ListBox
Dim Buffer As String
Dim WithEvents Timer1 As New Timer
Private Sub ListBoxTypeAhead_KeyDown(sender As Object, _
e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
Select Case e.KeyCode
Case Keys.A To Keys.Z, Keys.NumPad0 To Keys.NumPad9
e.SuppressKeyPress = True
Buffer &= Chr(e.KeyValue)
Me.SelectedIndex = Me.FindString(Buffer)
Timer1.Start()
Case Else
Timer1.Stop()
Buffer = ""
End Select
End Sub
Private Sub ListBoxTypeAhead_LostFocus(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.LostFocus
Timer1.Stop()
Buffer = ""
End Sub
Public Sub New()
Timer1.Interval = 2000
End Sub
Private Sub Timer1_Tick(sender As Object, e As System.EventArgs) Handles Timer1.Tick
Timer1.Stop()
Buffer = ""
End Sub
End Class
As you probably know, this feature is called 'type ahead,' and it's not built into the Winform ListBox (so you're not missing a property).
You can get the type-ahead functionality on the ListView control if you set its View property to List.
Public Function CheckIfExistInCombo(ByVal objCombo As Object, ByVal TextToFind As String) As Boolean
Dim NumOfItems As Object 'The Number Of Items In ComboBox
Dim IndexNum As Integer 'Index
NumOfItems = objCombo.ListCount
For IndexNum = 0 To NumOfItems - 1
If objCombo.List(IndexNum) = TextToFind Then
CheckIfExistInCombo = True
Exit Function
End If
Next IndexNum
CheckIfExistInCombo = False
End Function