Checkbox events when Form is opened and closed fire when form is reloaded - vb.net

First... I am open to skinning this cat a different way if I am going at it wrong to begin with. Using VB 2010 .net 4.0 and I am very much a beginner.
I am making a product billing application that has a main form and a subform with additional options. Whenever that subform is reopened after being opened once, the checkbox events that were selected are blank by default. If I recheck them (so someone can uncheck) then any that are rechecked all refire and increase the variable again.
I ultimately need to be able to open that second form after closing it, display any checkboxes that were selected before as selected again and not increase the variable in the process.
Main form Checkbox code to set booleans and increase or decrease subtotal variable of most used products.
Private Sub chkbox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkbox1.CheckedChanged
If chkbox1.Checked = True Then
bChkbox1 = True
Subtotal += 15
Else
bChkbox1 = False
Subtotal -= 15
End If
End Sub
Main form button to launch subform with all products listed.
Private Sub btnAllProducts_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAllProducts.Click
Form3.Show()
End Sub
Subform checkbox code works perfectly the first time it is opened but not when relaunched.
Private Sub chkbox2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkbox2.CheckedChanged
If chkbox2.Checked = True Then 'also tried without the nested if with same results
If Me.IsHandleCreated = True Then 'me.visible behaves the same way
MsgBox("form visible true")'launches after clicking button but before form is actually on screen
Form1.bcheckbox2 = True
Form1.Subtotal += 105
End If
Else
Form1.bcheckbox2 = False
Form1.Subtotal -= 105
End If
End Sub
Booleans are used to check boxes that were checked on the main page or when it was open before.
If Form1.bcheckbox2 = True Then
chkbox2.Checked = True
End If
As I said, I can completely rework the code if it makes sense to do so or just fix something if I have made some sort of mistake.
For example, I was thinking of changing to wipe the subtotal on each form load and rebuild it based off the toggled booleans but it seems like there should be a much more elegant way with less overhead and I am just doing something incorrectly.

It is not common to have to tell checks and radios to ignore events while loading the form. You just need an Ignore or Loaded flag:
Public Class Form1
Private ignore As Boolean = True
...
Private Sub Form1_Load(...
' do normal stuff
ignore = False ' should be the ONLY place it is set
End Sub
Private Sub CheckBox2_CheckedChanged(...
If ignore Then Exit Sub
End Sub
The Form Designer code will fire events as it creates the form and controls, which CAN be handy for initializing stuff but often it causes trouble. Some controls will even get the same event twice. There isnt really a "reload" action for forms. If you hide them, Show() won't fire the Load event again.
You can avoid the flag and manually add the handlers for the troublesome controls when the form loads, but that can be tedious if there are lots of them. Flags can be abused and misused, but if it is set in that one spot only, its fine.

If someone is looking for alternative or have similar problem here's my workaround to detect event change so checkbox wouldn't get triggered on re-load:
If ((Me.CheckBox2.Value <> Sheets(1).Range("t6").Value) And (Me.CheckBox2 = True)) = True Then
' do your stuff
Me.CheckBox2.Value = False
Else
Me.CheckBox2.Value = True
End If
Where Sheets(1).Range("t6").Value is where checkbox2 value is being stored.
I have this assigned to a msgbox input so when vbno event is being triggered else is executed.
Cheers.

Related

Unchecking a Previously Selected Checkbox when another checkbox is checked

My form has 3 checkboxes available to the User. When the User mistakenly checks one Checkbox and realizes the mistake then checks the correct Checkbox, I need the incorrect checked Checkbox to Uncheck automatically.
I have diligently searched the web but have been unable to find any sites that offer answers for VB 2010. Mostly they provide solutions for HTML, Excel, Java, etc.
Private Sub BeginnerForm_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
StartupForm.Close()
If Me.CheckBox1.Checked Then
Me.CheckBox2.Checked = False
Me.CheckBox3.Checked = False
ElseIf Me.CheckBox2.Checked Then
Me.CheckBox1.Checked = False
Me.CheckBox3.Checked = False
ElseIf Me.CheckBox3.Checked Then
Me.CheckBox1.Checked = False
Me.CheckBox2.Checked = False
End If
End Sub
The results of this code is that it does not uncheck the Checkbox(es). I get no error code, it just does not UNCHECK the Checkbox(es). I have also tried other code entries such as Me.Checkbox2.CheckState.Checked = CheckState.Unchecked to no avail. Trusting you can steer me in the right direction to UNCHECK a Checkbox when another Checkbox is CHECKED.
First of all, as mentioned by daShier, you place the code in the wrong event handler. Since you want to uncheck the other checkboxes when one is being checked, you must put the code in the either Click or CheckChanged event handler of all your checkboxes that take part in this selection logic. I would suggest to put in the CheckChanged event since it will be triggered even when your checkbox check state is changed through code in addition to through mouse or keyboard actions.
' declare variable to keep track of the previous selected checkbox
Dim prevSelectedCheckBox As CheckBox
' all checkboxes to be controlled are handled by this event handler
Private Sub CheckBoxes_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged, CheckBox2.CheckedChanged, CheckBox3.CheckedChanged
' first, identify which checkbox is triggering this event
Dim this As CheckBox = DirectCast(sender, CheckBox)
' if this event is triggered when this checkbox is being checked
If this.Checked Then
' if there is a checkbox previously selected/checked
If prevSelectedCheckBox IsNot Nothing Then
prevSelectedCheckBox.Checked = False ' uncheck it
End If
' now this checkbox is currently the checked one, save it to the variable
prevSelectedCheckBox = this
' if event is triggered by unchecking this checkbox, and this checkbox is the previously checked checkbox
ElseIf this.Equals(prevSelectedCheckBox) Then
' clear the variable since now, there is no checkbox is being checked
prevSelectedCheckBox = Nothing
End If
End Sub
However, if user can only select one option among the options represented by the checkboxes, you better use radio button instead.
It appears you are processing the code in the wrong handler. You are changing things when closing the form. Try moving the code to the CheckBoxx.CheckedChanged handlers:
Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
If CheckBox1.Checked Then
CheckBox2.Checked = False
CheckBox3.Checked = False
End Sub
UPDATE: I realize that your original code that I copied and pasted would cause a loop since the changing of the checkbox states would trigger the other routines. It's not necessary since you only need clear the other boxes if the box your user is clicking is checked.
You will need to add similar code to CheckBox2.CheckedChanged and CheckBox3.CheckedChanged as well.
Also, I should point out that you are trying to make checkboxes act as radio buttons. Why not replace the checkbox controls with radio buttons instead so that VB handles the one-only behavior for you?

Disable Button If Combox Input Deleted

In my project, I have a few textbox inputs, and some combo boxes with maybe 2 indexed items on a form. There's a button I'm disabling on load if no input is supplied to both textbox inputs, and it works great even if I delete out any text. However, I'm having issues with forcing the combo box to behave in the same manner. This work however:
Private Sub cboPickShirts_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cboPickShirts.SelectedIndexChanged
InputCheck_3 = True
If cboPickShirts.SelectedIndex < 0 Then
InputCheck_3 = False
End If
If InputCheck_3 = False Then
btnInputResult.Enabled = False
ElseIf InputCheck_3 = True Then
btnInputResult.Enabled = True
End If
End Sub
I have InputCheck_3 set up as a global variable in a Public Module. On form load, I'm disabling my button and it doesn't enable until I select one of the indexed items. My struggle to get the button disable again if any combo box text is entered and deleted out, leaving it null or empty. Any thoughts on what I'm missing or what I can add to get results? I guess I need a variable or event to notice the change (entering & deletion of text).
The problem you are having is that your SelectedIndexChanged event is not being triggered when you remove the selected item from your ComboBox. I would use the TextChanged event of your TextBox's and ComboBox and give it a common handler and check it that way. Something like this
Private Sub TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged, TextBox2.TextChanged, cboPickShirts.TextChanged
EnableCheck()
End Sub
Private Sub EnableCheck()
btnInputResult.Enabled = (String.IsNullOrEmpty(TextBox1.Text) And String.IsNullOrEmpty(TextBox2.Text) And ComboBox1.SelectedIndex = -1)
End Sub
You can also check that the comboBox is NullorEmpty the same way as the textbox's. As it stands right now the combobox will be enabled when the text no longer matches a selection.
One line code
btnInputResult.Enabled = If((cboPickShirts.SelectedIndex<0),False, True)

Forms acting unexpectedly

I'll try to explain this best I can.
I have windows form application that contaions numerous forms. The first form
to open is a non modal form that acts as command form to issue various formats to
the underlying reservation program. A second form also opens which is basically my
Main form for the application. This form contains multiple check boxes to run methods
that make changes to the reservation program. This form is also modeless. Each box that
is checked runs concurrently and performs methods to delete, change and add to the
res program below. Various boxes may be checked at any given time. Below is code to
handle the checkboxes:
Private Sub frmOWTMain_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
If e.KeyCode = Keys.Enter Then
Me.Hide() 'here i want to hide the OWTMain form
Call ckforPNR()
If Me.cbPricing.Checked Then
Call doPricing()
Me.cbPricing.Checked = false
End If
If Me.cbUdids.Checked Then
frmUdids.Show()
Me.cbUdids.Checked = False
End If
If Me.cbMod.Checked Then
Call doModUdids()
End If
If Me.cbFare.Checked Then
Call doFareSavings()
Me.cbFare.Checked = False
End If
End If
Me.show() 'This is the problem. This runs during method calls. All I'm
'looking to do is re display the OWTMain form.
End Sub
At this point I would want to re display the OWTMain form above. This is
where I am having an issue. As you can see, a number of methods are called
which involve showing other forms to the user. I do NOT want any of these
forms to be modal because I want the original first opened form to still be
able to issue commands to the res program toview information needed by the other forms.
Here is an example of some of the method calls:
Private Sub doPricing()
Dim myPrice As New Pricing 'a call to another class that handles pricing
If myPrice.getTQT = False Then
frmAddPricing.ShowDialog() 'showing new forms
Else
frmCurPricing.ShowDialog()
End If
End Sub
Private Sub doFareSavings()
Dim myPrice As New Pricing
If myPrice.checkForFS = False Then
frmFS.ShowDialog() 'showing new forms
End If
If myPrice.checkForFS = True Then
frmFSVerify.ShowDialog()
End If
End Sub
When I call any of these methods the form OWTMain shows prematurely while other
forms from the called method are still running. I expected the code at the top to run
in order of the calls but that is not the case. I just want to re display the OWTMain
form after all the code is run. I have not been able to figure this out without
creating a ton of code to minipulate the opening and closing of the windows.
Any help with this would be greatly appreciated. Thank you.
John
This will check if all sub forms are closed and then re-show the main form.
remove the exitsing me.show()
Public Sub ReShowMainForm()
' add all sub forms to this check
if frmFS.Visible = false andalso
frmUdids.Visible = false andalso
frmFSVerify.Visble = false then
Me.Show
End If
End Sub
change xyzForm.Show to xyzForm.Show(me) to make the main form available as parent to the sub forms.
Handle the FormClosed event in each sub form and add the following code
DirectCast( me.parent, frmOWTMain).ReShowMainForm()

Auto Login Procedure (Hide Form) vb.NET Windows Forms

Okay, I am having a bit of trouble here. I am creating a log in window for an application, but I am trying to get the application to automatically log in (i.e. perform the functions that happen when the user logs in) when it starts, without showing the log in screen, if the settings already have a stored email and password. I have a notification System Tray Icon that shows when the app is running, and when the form is not visible, a balloon notification pops up so the user knows that it is still running, and click on the icon to open the log in screen.
Take a look at the following code. I know that this If Not event is being called and working correctly, because it performs everything inside the statement EXCEPT hiding the form. Why does it not change to invisible? I also tried Me.Hide, and same issue. The Balloon Notification pops up, the text boxes fill with the previously stored data...but the form stays visible...
Private Sub RadFrmLogin_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Checks settings to see if email and password have already been stored and enters them into text fields, proceeds to automatically update access list
If Not String.IsNullOrEmpty(My.Settings.Email) And Not String.IsNullOrEmpty(My.Settings.Password) Then
TxtEmail.Text = My.Settings.Email
TxtPassword.Text = My.Settings.Password
Me.Visible = False
'Displays Balloon Tip
ntfySystemTrayIcon.ShowBalloonTip(800)
End If
End Sub
As an added note, I added a test button to hide the form, and it works perfectly:
Private Sub BtnHide_Click(sender As Object, e As EventArgs) Handles BtnHide.Click
'Hides form(for testing notification tray icon and balloon tip
Me.Visible = False
ntfySystemTrayIcon.ShowBalloonTip(1000)
End Sub
(removed my stupid default debug instructions since they did not help at all)
Update
okay, so there were similar questions before, take a look here: C#/.NET - WinForms - Instantiate a Form without showing it
short explanation: usually something like form1.show is used, so it is always changed to visible = true after the form_load is finished.
Either use the instructed event form_shown and add the visible=false
or another user recommended to change start properties to minimized and activate to hide program in taskbar. This helps to prevent that annoying flickering. I guess after that you can change the options back.
Update 2 The following seems to work well:
Private _IsVisible As Boolean
Public Property IsVisible() As Boolean
Get
Return _IsVisible
End Get
Set(ByVal value As Boolean)
_IsVisible = value
If _IsVisible Then
Me.WindowState = FormWindowState.Normal
Me.ShowInTaskbar = True
Me.Visible = True
Me.Activate()
Else
Me.WindowState = FormWindowState.Minimized
Me.ShowInTaskbar = False
Me.Visible = False
End If
End Set
End Property
If you want to get rid of the small taskbar flickering, then change the forms property showInTaskbar. When it is changed during the form_load, then there seem to be a short movement at the taskbar.
And to make it perfect, in form.Shown add following code:
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
Me.Visible = IsVisible
End Sub
now it is enough to use
IsVisible = False
in form_Load, or if you want to show it
IsVisible = True
Just some ideas:
If all your tasks are completed in the _Load event try just calling End. Of course that would remove your tray icon as well.
Another possibility is to call Me.Visible in the _Shown event. This may cause a flash on the screen. If so perhaps you could position the form off the screen in _Load.

NumericUpDown.value is not saved in the User Settings

I have a NumericUpDown Control on a form. In the Application Settings / Properties Binding, for the value parameter, i can't select my USER setting called : Heures (Integer / User).
I tried to save the value by this way :
Private Sub NumericUpDownHeures_Leave(sender As System.Object, e As System.EventArgs) Handles NumericUpDownHeures.Leave
My.Settings.Heures = NumericUpDownHeures.Value
My.Settings.Save()
End Sub
But it's not saved.
No problem for other settings (String / User). But i don't understand why the settings (Integer / User) are not saved.
Please help, Thanks.
As you are putting "NumericUpDown1.Value" you have to set the value at My.Settings.Heures to decimal.
In Form1_Load add:
NumericUpDownHeures.Value = My.Settings.Heures
and add to the event listener for your button or other widget:
My.Settings.Heures = NumericUpDownHeures.Value
I would guess the issue is that the Leave event is not being fired as you expect it to be, especially if the user just clicks the up/down arrows. I suspect that it is only fired when the user actually clicks into the value area, then leaves. You could verify this by debugging to see if your code is ever hit or by showing a simple msgbox from that event.
I think that you will have better luck if you hook the LostFocus or ValueChanged event.
I want to add to this as well for anyone looking at this in the future.
Save your settings as shown already by putting
My.Settings.Heures = NumericUpDownHeures.Value into your ValueChanged event, and then doing reverse in the form load event.
The problem is, this value changed event fires before the form load when you first initialize, so it will keep defaulting to whatever value you have set in the designer because you're overwriting the setting value with the designer value.
To get around this, you need a private/public boolean at the top of your code that is only set to true once your form has loaded (set to true at the bottom of your form_load event), then you can add the condition to the ValueChanged event checking if the form is loaded yet or not. If it is, then change the setting value, if not, then don't.
An example:
Private IsFormLoaded As Boolean = False
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
NumericUpDown1.Value = My.Settings.SavedNumValue
IsFormLoaded = True
End Sub
Private Sub NumericUpDown1_ValueChanged(sender As Object, e As EventArgs) Handles NumericUpDown1.ValueChanged
If IsFormLoaded = False Then Exit Sub
My.Settings.SavedNumValue = NumericUpDown1.Value
End Sub
OR
Private Sub NumericUpDown1_ValueChanged(sender As Object, e As EventArgs) Handles NumericUpDown1.ValueChanged
If IsFormLoaded Then
My.Settings.SavedNumValue = NumericUpDown1.Value
End If
End Sub