How can I make textboxes appear/disappear depending on a checkbox state? - vb.net

I have an application that I'm developing for a school project. This is what the application looks like
Essentially whenever one of the CheckBoxes is checked, a TextBox.Visible property is changed to true and is supposed to appear underneath the checkbox. You can have all three of them checked (or any combination checked) if you like, as long as when you uncheck it the TextBox disappears and the CheckBox appears empty/unchecked.
I've gotten to the point where I can make the TextBoxes appear and disappear but the TextBoxes are never empty. There's always a black square there that looks like this
Those black squares don't go away and I'm not sure exactly what the problem is. The TextBox also only appears when the CheckBox has that square as opposed to an actual check which is what is required. I have used a combination of If...ElseIf statements and Select Cases, which haven't done it. I've tried a few different events like CheckChanged and Click.
This is the code that I currently use that allows me to toggle the boxes.
Private Sub chkBox_Click(sender As Object, e As EventArgs) Handles chkBox.Click
If chkBox.Checked = False Then
txtBox.Visible = False
txtBox.Text = ""
Else
txtBox.Visible = True
End If
chkBox.Checked = True
End Sub
Private Sub chkLawn_Click(sender As Object, e As EventArgs) Handles chkLawn.Click
If chkLawn.Checked = False Then
txtLawn.Visible = False
txtLawn.Text = ""
Else
txtLawn.Visible = True
End If
chkLawn.Checked = True
End Sub
Private Sub chkPav_Click(sender As Object, e As EventArgs) Handles chkPav.Click
If chkPav.Checked = False Then
txtPav.Visible = False
txtPav.Text = ""
Else
txtPav.Visible = True
End If
chkPav.Checked = True
End Sub
If you guys can think of a solution or could point me in the right direction I would appreciate that.

I'd recommend this in the form load to setup a relationship between the checkboxes and the textboxes:
chkBox.Tag = txtBox
chkLawn.Tag = txtLawn
chkPav.Tag = txtPav
Then one handler:
Private Sub chkBox_Click(sender As Object, e As EventArgs) Handles chkBox.Click, chkPav.Click, chkLawn.Click
CType(sender.Tag, TextBox).Visible = CType(sender, Checkbox).Checked
End Sub

Try to remove the chkPav.Checked = True, chkLawn.Checked = True and chkBox.Checked = True in your .click events.
Also, i would recommand to use the "CheckStateChanged" vb.net event.

This will handle all your CheckBox.CheckChanged events. It finds the TextBox based on the name of the CheckBox. So just name them the same as you have (i.e. chkA and txtA).
Private textBoxPrefix As String = "txt"
Private checkBoxPrefix As String = "chk"
Private Sub chk_CheckedChanged(sender As Object, e As EventArgs) Handles chkBox.CheckedChanged, chkLawn.CheckedChanged, chkPav.CheckedChanged
Dim chk = CType(sender, CheckBox)
Dim suffix = chk.Name.Substring(checkBoxPrefix.Length)
Dim txt = Me.Controls().Find(textBoxPrefix & suffix, True).Single()
txt.Visible = chk.Checked
txt.Text = If(chk.Checked, "", txt.Text)
End Sub
Making it a little more scaleable, add handlers to all CheckBoxes in the GroupBox in Form_Load programmatically. (remove Handles chkBox.CheckedChanged, chkLawn.CheckedChanged, chkPav.CheckedChanged from the event handler declaration)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' assuming the GroupBox is named gbTickets, add all handlers programmatically
For Each chk As CheckBox In Me.gbTickets.Controls.OfType(Of CheckBox)
AddHandler chk.CheckedChanged, AddressOf chk_CheckedChanged
Next
End Sub

Related

Update DataGridViewCheckBoxColumn checkbox on CellClick

I have a DataGridView with a DataGridViewCheckBoxColumn column. The cell size is larger than the checkbox so to make it user-friendly I want the CellClick event to act as if the checkbox itself was clicked.
At the moment I do this in my CellClick event:
If e.ColumnIndex = dgv.Columns("CONFIRM").Index Then
If CBool(dgv.Item("CONFIRM", e.RowIndex).Value) = True Then
dgv.Item("CONFIRM", e.RowIndex).Value = False
Else
dgv.Item("CONFIRM", e.RowIndex).Value = True
End If
End If
However, the checkbox does not actually change state until after the cell loses focus. I've seen many suggestions about handling different events (CellValueChanged, CurrentCellDirtyStateChanged) (e.g. http://www.codingeverything.com/2013/01/firing-datagridview-cellvaluechanged.html) and committing changes with:
If dgvDownloads.IsCurrentCellDirty Then
dgvDownloads.CommitEdit(DataGridViewDataErrorContexts.Commit)
End If
However this doesn't work, the dgv flickers but the checkbox doesn't change checked state.
How can I force the checkbox in a DataGridViewCheckBoxColumn to update it's state when the containing cell is clicked?
Try it more like this:
Public Class FormDGV
Private Sub FormDGV_Load(sender As Object, e As EventArgs) Handles MyBase.Load
With DataGridView1
.Columns.Add(New DataGridViewCheckBoxColumn With {
.Name = "Confirm",
.HeaderText = "Confirm"})
End With
End Sub
Private Sub DataGridView1_CurrentCellDirtyStateChanged(sender As Object, e As EventArgs) Handles DataGridView1.CurrentCellDirtyStateChanged
If DataGridView1.IsCurrentCellDirty Then
DataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
End If
End Sub
Private Sub DataGridView1_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
If CType(DataGridView1.Rows(e.RowIndex).Cells("Confirm").Value, Boolean) Then
DataGridView1.Rows(e.RowIndex).Cells("Confirm").Value = False
Else
DataGridView1.Rows(e.RowIndex).Cells("Confirm").Value = True
End If
Validate()
End Sub
End Class

VB .net Change text of selected textbox on button click

I have 10 buttons and I want to click on a button so it changes text of the focused textbox and switch to next textbox.
i tried this:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TextBox1.Focus()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If TextBox1.Focus Then
TextBox1.Text = "1"
TextBox1.Enabled = False
TextBox2.Focus()
TextBox2.Enabled = True
End If
If TextBox2.Focus Then
TextBox2.Text = "1"
TextBox2.Enabled = False
TextBox3.Focus()
TextBox3.Enabled = True
End If
If TextBox3.Focus Then
TextBox3.Text = "1"
TextBox3.Enebled= False
TextBox4.Focus()
TextBox4.Enabled = True
End If
End Sub
But it writes the value in every textbox instead of just going to the next textboxt
This code does not do what you think it does:
If TextBox1.Focus Then
Focus is not a boolean property. In VB.Net, you can call methods without parentheses, and that's what you're doing here. The conditional block actually tries to set the focus. And since this is always gonna succeed unless you explicitly handle the event and block it, all of those If conditions result in True.
To find which control has focus, do this:
Public Shared Function FindFocusedControl(control As Control) As Control
Dim container = TryCast(control,IContainerControl)
While container IsNot Nothing
control = container.ActiveControl
container = TryCast(control, IContainerControl)
End While
Return control
End Function
In your Click event handler, you are calling the Focus method of each TextBox in turn and then populating them if it succeeds. It will succeed every time so you populate every TextBox.
I suspect that what you meant to do was test the Focused property rather than call the Focus method. That would make more sense because then it would only populate the TextBox that had focus. That is still flawed though, because the Button that you just clicked will have focus, so you won't actually populate any TextBox.
You have two main choices here. Firstly, you could use a custom Button control that will not take focus when it is clicked. That way, the TextBox that had focus when you clicked will still have focus. Alternatively, you could remember which control last had focus by assigning it to a field and using that. That's probably the way that I'd go.
Here's a quick (i.e. not rigorous) example of the second option:
Private lastActiveControl As Control
Private Sub TextBoxes_Leave(sender As Object, e As EventArgs) Handles TextBox4.Leave,
TextBox3.Leave,
TextBox2.Leave,
TextBox1.Leave
lastActiveControl = DirectCast(sender, Control)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim textBoxes = New Control() {TextBox1, TextBox2, TextBox3, TextBox4}
Dim lastTextBoxIndex = Array.IndexOf(textBoxes, lastActiveControl)
If lastTextBoxIndex <> -1 Then
Dim nextTextBoxIndex = (lastTextBoxIndex + 1) Mod textBoxes.Length
Dim nextTextBox = textBoxes(nextTextBoxIndex)
lastActiveControl.Text = "1"
lastActiveControl.Enabled = False
nextTextBox.Enabled = True
nextTextBox.Select()
End If
End Sub

Variable depending on Tab focus

i have question that is bugging me for quite some time but im unable to get this around my mind.
So i have a program that contains 8 tabs, all using same formula for calculating when i click's the button on this page but base value is depending on whitch tab is selected and which button is clicked
variables a1 and a2 are the same values accessing exacly the same database just like b1&b2 and c1&c2 working as comboboxes
Private Sub Calculate() Handles button1.Click
value1 = 0.5
sum1 = a1.selectedValue*b1.SelectedValue*c1.SelectedValue*value1
textbox1.value = sum1.value
Private Sub Calculate2() Handles button2.Click
value2 = 0.55
sum2 = a1.selectedValue*b2.selectedValue*c2.selectedValue*value2
texbox2.value = sum2.value
is there any way to make value by depending on the tab that's focused and simplify it? like
Private Sub Calculate(sender As Object, e As EventArgs) Handles button1.Click, button2.Click, button3.Click
if tabpage1 is focus then
value = 0.05
elseif tabpage2 is focus then
value = 0.55
end if
if a1 is selected then
a=a1.value
elseif a2.is selected then
a=a2.value
......
endif
.......
sum = a*b*c*value
if tabpage1 is focus then
textbox1.value = sum.value
else
....
endif
??
i know code above is far from "simple" and actually the handling buttons in each sub is maybe hmmm... better? Just looking at other perspectives to do this 8 tabs in just one sub
I'd suggest that the best solution is something like this:
Dim selectedTab = TabControl1.SelectedTab
Dim tb = selectedTab.Controls.OfType(Of TextBox)().First()
Dim value = CInt(selectedTab.Tag)
'Use tb and value here.
You just need to set the Tag property of each TabPage to the appropriate value and you may need to adjust that second line if there are other TextBoxes on each page or it's inside another container. There's obviously multiple ComboBoxes on each page so that part might look like this:
Dim cbs = selectedTab.Controls.OfType(Of ComboBox)().ToArray()
Dim cbb = cbs(0)
Dim cbc = cbs(1)
you can use method Focused or ActiveControl or SelectedTab/Index as :
Private Sub Calculate(sender As Object, e As EventArgs) Handles button1.Click, button2.Click, button3.Click
If sender Is button1 Then '' Button1 is clicked
If TabControl1.SelectedTab Is tabpage1 Then
'' If tabpage1.Focused OrElse Me.ActiveControl Is tabpage1 Then '' Tabpage1 if focused Or Tabpage1 is Active Control
'' Your Code
End If
End If
If sender Is button2 Then '' Button2 is clicked
If TabControl1.SelectedTab Is tabpage2 Then
'' If tabpage2.Focused OrElse Me.ActiveControl Is tabpage2 Then '' Tabpage2 if focused or Tabpage2 is Active Control
'' Your Code
End If
End If
End Sub

vb.net - enable/disable a button depending on user input

As I'm putting the finishing touches on my program I'm having some troubles.
Theres several user inputs and a submit button, once the inputs has been filled I wish to enable the submit button, else the button should be disabled. This is what I have:
Private Sub ButtonControl(sender As System.Object, e As System.EventArgs) Handles Input1.Validated
If Input1.Text = "" Then
ButtonSubmit.Enabled = False
ElseIf Input1.Text <> "" Then
ButtonSubmit.Enabled = True
End If
End Sub
The thing is it disables nomatter what and then it doesnt enable when my input is filed
Your code will work if you have another control that can receive the focus. Control Validation occurs on the loss of focus. If you need to have just one focusable item active you will need to use either KeyPress, KeyDown or Textchanged events to enable your button, also make sure that the CausesValidation property of your TextBox is true.
I would also make the method more generic so you could call it from multiple textbox's by using the sender object to access the textbox that raised the event. Also if you have a True/False condition you only need to do the comparison in the first if statement and then you just use an else not an elseif.
for example:
Private Sub ButtonControl(sender As System.Object, e As System.EventArgs) Handles Input1.Validated
If DirectCast(sender, TextBox).Text = "" Then
ButtonSubmit.Enabled = False
Else
ButtonSubmit.Enabled = True
End If
End Sub
You can also use the String.IsNullOrWhiteSpace Method to check if just spaces have been entered if you are using the 4.0 framework or above. Like this TextChanged EventHandler.
Private Sub ButtonControl(sender As Object, e As EventArgs) Handles Input1.TextChanged
If String.IsNullOrWhiteSpace(DirectCast(sender, TextBox).Text) Then
ButtonSubmit.Enabled = False
Else
ButtonSubmit.Enabled = True
End If
End Sub
You are going to need to use the TextBox "TextChanged" event, and be sure to set each Textbox AutoPostback="True". You can use an UpdatePanel to make the postbacks that occur on each Textbox you wish to validate less obnoxious to your end-user.
So, your textbox (if you have many, make sure they all have the OnTextChanged="ValidateForm":
<asp:TextBox ID="Input1" runat="server" OnTextChanged="Validate_TextChanged" />
Inside your textchanged ("ValidateForm") event (which each Textbox is attached to), one quick to implement route to do would just be
' Validation inside this event
Protected Sub Validate_TextChanged(sender As Object, e As EventArgs)
if Input1.text <> "" AndAlso Input2.text <> "" AndAlso ' ...etc.
End Sub
If you go the route of the UpdatePanel, you may find this useful.
This is the kind of thing I would do:
Private Sub TextBoxes_TextChanged( _
ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles _
TextBox1.TextChanged, _
TextBox2.TextChanged, _
TextBox3.TextChanged
Dim textBoxes = { TextBox1, TextBox2, TextBox3 }
Button1.Enabled = textBoxes.All(Function (tb) tb.Text <> "")
End Sub
You can then add as many text boxes in to the textBoxes array as you need to check. Just make sure that the text boxes to the Handles list.
Private Sub TextBox1_TextChanged(sender As System.Object, e As System.EventArgs) Handles TextBox1.TextChanged
If TextBox1.Text.Length > 0 Then
Me.Button1.Enabled = True
Else
Me.Button1.Enabled = False
End If
End Sub
Do that code in the Input1_TextChanged event
This is what I did and worked:
Dim CheckInput1 As Boolean
Private Sub Input1_TextChanged(sender As Object, e As EventArgs) Handles Input1.TextChanged, Input1.Enter
CheckInput1 = True
If Input1.Text = "" Then
CheckInput1 = False
End If
If CheckInput1 = False Then
ButtonSubmit.Enabled = False
ElseIf CheckInput1 = True Then
ButtonSubmit.Enabled = True
End If
End Sub
There must be a more efficient code that this but I think this solves your problem.

how to keep the selected checkbox when the form is close?

i got some checkbox and i want to retain the selected ones when i reopen the form.
here's what i done almost but it only returns the very first selected checkbox only..
For Each strItm As String In str
For Each ctl As Control In Me.Controls
If TypeOf ctl Is CheckBox Then
If ctl.Text = strItm Then
Dim cb As CheckBox = DirectCast(ctl, CheckBox)
cb.Checked = True
End If
End If
Next
Next
and anyone help me out. tnx in advance. more power.
An easy way is to create a global bool variable for each check box that holds true when its check box is checked and false when it's not. Then when you close your form those variables will keep their values. Once you re-open the form you can set the checked property back matching those variables through the form Load event
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
checkbo1.checked = globalVar1
checkbo2.checked = globalVar2
checkbo3.checked = globalVar3
End Sub
in the ParentForm:
Dim frm As New ChildForm
frm.ShowDialog()
In the ChildForm
Public Shared Chk1 As Boolean
Private Sub ChildForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
CheckBox1.Checked = Chk1
End Sub
Also you need to update the vaule here when changed:
If ctl.Text = strItm Then
Dim cb As CheckBox = DirectCast(ctl, CheckBox)
cb.Checked = True
Chk1 = True
End If