Using a timer to update form - VB.Net - vb.net

I want to display the status of aspects of my application on a form.
I tried adding a timer to the form. Every 10 seconds the timer runs and checks a database for a particular status, then changes elements on the form based on the status.
This works fine for changing the colour of menu items, but when I try and make an image (in)visible on the form, I get a cross-thread error.
Should I be using a timer, Backgroundworker or something else?
Does someone have a basic bit of code that will do this elegantly?
Private WithEvents tmrMain As New System.Timers.Timer(10000)
Private Sub frmMaster_Load(sender As Object, e As EventArgs) Handles Me.Load
tmrMain.Enabled = True
tmrMain.Start()
End Sub
Private Sub tmrMain_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles tmrMain.Elapsed
Dim TRunning As Boolean = True
TRunning = BTools.CheckImportRunningStatus '' This gets the on/off status from the DB
If TRunning Then
miFileMYOBImport.ForeColor = Color.Red '' Change menu color
pbMYOBDownload.Visible = True '' Make image visible
Else
miFileMYOBImport.ForeColor = Color.DarkGreen
pbMYOBDownload.Visible = False
End If
End Sub

Try:
Private Sub MakeImageVisible(ByVal control As Control, ByVal visible As Boolean)
If control.InvokeRequired Then
control.BeginInvoke(New Action(Of Control, Boolean)(AddressOf MakeImageVisible), control, visible)
Else
control.Visible = visible
End If
End Sub
Private Sub tmrMain_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles tmrMain.Elapsed
Dim TRunning As Boolean = True
TRunning = BTools.CheckImportRunningStatus '' This gets the on/off status from the DB
If TRunning Then
miFileMYOBImport.ForeColor = Color.Red '' Change menu color
Else
miFileMYOBImport.ForeColor = Color.DarkGreen
End If
MakeImageVisible(pbMYOBDownload, TRunning) ' Make image visible or invisible
End Sub

Related

How can I make textboxes appear/disappear depending on a checkbox state?

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

How to force form to show again on application startup?

I have a Help form that shows for the first time when the application is started. After the initial startup, that form doesn't show up anymore. Is there a way to reset the show form? Here's my code to only show it once base on the application setting. When the application exit, the application sets the showform to false. <<--Need to reset on the user's computer. Reason i need this is if i have a update to application, i need to show user the updates on that help form.
Private Sub AboutInformation_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
If IsNewVersionAvailable() = True Then
Dim showNextTime As Boolean
showNextTime = My.Settings.LoadAboutForm
If showNextTime = False Then
Show()
Location = New Point(0, 0)
showNextTime = True
My.Settings.LoadAboutForm = showNextTime
My.Settings.Save()
Else
Close()
myForm.Show()
End If
End if
End Sub
For anyone looking for a answer, I save my currentVersion in the application setting on the main form closed and on startup of the help form it checks if the previous version matches the updated version, if it doesn't it will show help form, if it does, it skips to the main for.
Private Sub AboutInformation_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
Location = New Point(0, 0)
'If ApplicationDeployment.IsNetworkDeployed Then
Try
Dim thisVersion As Version = ApplicationDeployment.CurrentDeployment.CurrentVersion
If thisVersion.ToString = My.Settings.CurrentVersion Then
Dim showNextTime As Boolean
showNextTime = My.Settings.LoadAboutForm
If showNextTime = False Then
Show()
Location = New Point(0, 0)
showNextTime = True
My.Settings.LoadAboutForm = showNextTime
My.Settings.Save()
Else
Close()
myMainForm.Show()
End If
End If
Catch ex As Exception
'MsgBox(ex.Message)
End Try
End Sub
'Saving setting for main form closed.
Private Sub myMainForm_FormClosed(ByVal sender As Object, ByVal e As FormClosedEventArgs) Handles Me.FormClosed
If ApplicationDeployment.IsNetworkDeployed Then
Dim currentVersion As Version = ApplicationDeployment.CurrentDeployment.CurrentVersion
Debug.Print(currentVersion.ToString)
My.Settings.CurrentVersion = currentVersion.ToString
End If
My.Settings.Save()
End Sub

Disable Tab Control when pressing Button VB.NET

I would like to ask if how could possibly disable tabs in tabcontrol.
This is what the codes looks like when disable:
Public Sub TabControl1_Selecting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TabControlCancelEventArgs) Handles TabControl1.Selecting
If e.TabPageIndex = 3 Then
e.Cancel = True
End If
End Sub
This code only disable while you load the form
I was trying to convert a code from c# however it doesn't work as I expected.
See this code:
Public Sub EnableTabs(ByVal Page As TabPage, ByVal bolFlag As Boolean)
EnableControls(Page.Controls, bolFlag)
End Sub
Private Sub EnableControls(ByVal Ctrls As Control.ControlCollection, ByVal bolFlag As Boolean)
For Each Ctrl As Control In Ctrls
Ctrl.Enabled = bolFlag
EnableControls(Ctrl.Controls, bolFlag)
Next
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'I have problems with this line
EnableTabs(TabControl1.TabPages(TabControl1.SelectedIndex) = 0, False)
End Sub
Is there anyway that I could possibly disable a tab while clicking a button?
Let me know!
Thanks,
Regards,
Alvin
Try this:
Private Sub Button_Click( sender As Object, e As EventArgs) Handles Button.Click
Dim tabPage As TabPage
For Each tabPage In TabControl1.TabPages
If tabPage.Text ="TabPage1"
tabPage.Enabled =False
End If
Next
End Sub
or
Private Sub Button1_Click( sender As Object, e As EventArgs) Handles Button1.Click
TabControl1.TabPages(0).Enabled =false
End Sub
Yet another answer.
At some point if you want to disable a tab - use this code at the appropriate point
TabControl1.TabPages(x).Enabled = False
Where x is the zero-based index of the tab page you want to disable.
When the user clicks on a TabPage, the Selecting event fires for the whole control. Using the e eventargs parameter you can see the index of the TabPage being selected. The code in this event checks to see if it is disabled and if so, cancels the tab click.
Private Sub TabControl1_Selecting(sender As Object, e As TabControlCancelEventArgs) Handles TabControl1.Selecting
If e.TabPage.Enabled = False Then
e.Cancel = True
End If
End Sub
I already answered it. Anyhow, I would like to share it for you guys.
I just change the code from:
EnableTabs(TabControl1.TabPages(TabControl1.SelectedIndex) = 0, False)
to:
EnableTabs(TabControl1.TabPages(1), False)
This code only the contain of tab not by disable while selecting/clicking the tab header. I think I just use this one for now. If you have other source of code that is useful enough. Just leave on the answer section below. I loved to hear them all.
Thanks anyway.
Regards,
Alvin
I have already my own answer based on it. And I used this code right now, for example I have 3 tabs with 0-2 index respectively.
Public Sub Tab0Flag As Boolean
Public Sub Tab1Flag As Boolean
Public Sub Tab2Flag As Boolean
Public Sub TabControl1_Selecting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TabControlCancelEventArgs) Handles TabControl1.Selecting
If e.TabPageIndex = 0 Then
e.Cancel = Tab0Flag
End If
If e.TabPageIndex = 1 Then
e.Cancel = Tab1Flag
End If
If e.TabPageIndex = 2 Then
e.Cancel = Tab2Flag
End If
End Sub
Private Sub EnableTabs(ByVal Tab0 As Boolean, ByVal Tab1 As Boolean, ByVal Tab2 As Boolean)
Tab0Flag = Tab0
Tab1Flag = Tab1
Tab2Flag = Tab2
End Sub
Private Sub frmG_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'I'll Only Disable the 2nd tab
EnableTabs(False, True, False)
End Sub

How to show or load Main Form (MDIParent1) after RunWorkerCompleted in VB.NET

I have a many Splash Form, MDIParent Form and others form. My Scenario process like this: Project Statup - SPlash Form, After Splash Form show first time and check some files, etc and after checking will be show MDIParent1 and splash form will close automatically.
This below is my code inside Splash form:
Public Class frmSplash
Dim m_CountTo As Integer = 0 ' How many time to loop.
Private Sub My_BgWorker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles My_BgWorker.DoWork
For i As Integer = 0 To m_CountTo
' Has the background worker be told to stop?
If My_BgWorker.CancellationPending Then
' Set Cancel to True
e.Cancel = True
Exit For
End If
System.Threading.Thread.Sleep(100) ' Sleep for 1 Second
' Report The progress of the Background Worker.
My_BgWorker.ReportProgress(CInt((i / m_CountTo) * 100))
SetLabelText_ThreadSafe(Me.lblPercent, FormatPercent(i / m_CountTo, 2))
If i = 10 Then
SetLabelText_ThreadSafe(Me.lblMessages, "Initializing..")
ElseIf i = 40 Then
SetLabelText_ThreadSafe(Me.lblMessages, "Checking Mysql Service..")
ElseIf i = 50 Then
If CheckIfServiceIsRunning("MySql") = False Then
' Is the Background Worker do some work?
If My_BgWorker.IsBusy Then
'If it supports cancellation, Cancel It
If My_BgWorker.WorkerSupportsCancellation Then
' Tell the Background Worker to stop working.
My_BgWorker.CancelAsync()
End If
End If
SetButton_ThreadSafe(Me.btnExit, True)
Exit Sub
End If
ElseIf i = 70 Then
SetLabelText_ThreadSafe(Me.lblMessages, "Checking Internet Connection..")
ElseIf i = 80 Then
If CheckURL("http://www.google.com") = False Then
SetLabelText_ThreadSafe(Me.lblMessages, "No Internet Connection..")
End If
Next
End Sub
Private Sub My_BgWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles My_BgWorker.ProgressChanged
' Update the progress bar
Me.ProgressBar1.Value = e.ProgressPercentage
End Sub
Private Sub My_BgWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles My_BgWorker.RunWorkerCompleted
If e.Cancelled Then
Me.lblMessages.Text = "Cancelled"
Else
Me.lblMessages.Text = "Completed"
My_BgWorker.CancelAsync()
Me.Close()
MDIParent1.Show()
End If
End Sub
Delegate Sub SetLabelText_Delegate(ByVal [Label] As Label, ByVal [text] As String)
' The delegates subroutine.
Private Sub SetLabelText_ThreadSafe(ByVal [Label] As Label, ByVal [text] As String)
' InvokeRequired required compares the thread ID of the calling thread to the thread ID of the creating thread.
' If these threads are different, it returns true.
If [Label].InvokeRequired Then
Dim MyDelegate As New SetLabelText_Delegate(AddressOf SetLabelText_ThreadSafe)
Me.Invoke(MyDelegate, New Object() {[Label], [text]})
Else
[Label].Text = [text]
End If
End Sub
Delegate Sub SetButton_Delegate(ByVal [Button] As Button, ByVal [visible] As Boolean)
' The delegates subroutine.
Private Sub SetButton_ThreadSafe(ByVal [Button] As Button, ByVal [visible] As Boolean)
' InvokeRequired required compares the thread ID of the calling thread to the thread ID of the creating thread.
' If these threads are different, it returns true.
If [Button].InvokeRequired Then
Dim MyDelegate As New SetButton_Delegate(AddressOf SetButton_ThreadSafe)
Me.Invoke(MyDelegate, New Object() {[Button], [visible]})
Else
[Button].Visible = [visible]
End If
End Sub
Private Sub frmSplash_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Set the count to 100
m_CountTo = 100
' Start the Background Worker working
My_BgWorker.RunWorkerAsync()
End Sub
Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExit.Click
' Is the Background Worker do some work?
If My_BgWorker.IsBusy Then
'If it supports cancellation, Cancel It
If My_BgWorker.WorkerSupportsCancellation Then
' Tell the Background Worker to stop working.
My_BgWorker.CancelAsync()
End If
End If
' Enable to Start Button
Me.btnExit.Enabled = True
' Disable to Stop Button
Me.btnExit.Enabled = False
Application.Exit()
End Sub
End Class
Anyone can help me, whats the best way to show MDIParent (the main form) in sub RunWorkerCompleted, after splash form finish to loading.
In my code above, MDIParent1 cannot show correctly because after show, application closed/terminated.
In Project --> Properties, set your MDIParent as the "Startup form", and set your Splash Form as the "Splash form".
Now place all of your initialization checks in the Load() event of the MDIParent without using any Threading or BackgroundWorkers. The Splash Form will display for as long as the Load() event takes to complete, then will close automatically.
To update the splash from your MDIParent, cast My.Application.SplashScreen to your Splash Form type, and use delegates/Invoke() as you're already doing.
Here's a silly example:
Public Class frmMdiParent
Private Sub frmMdiParent_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' initialization...
Dim splash As frmSplash = DirectCast(My.Application.SplashScreen, frmSplash)
Dim numberSteps As Integer = 10
For i As Integer = 1 To numberSteps
splash.Invoke(Sub()
splash.Label1.Text = "Step " & i & " of " & numberSteps
End Sub)
System.Threading.Thread.Sleep(1000)
Next
' some other stuff...
Dim child As New Form
child.MdiParent = Me
child.Text = "Some MdiChild..."
child.Show()
End Sub
End Class

Making combobox visible when it is disabled

I am disabling combobox in VB.net.
But in disable mode it not visible properly.
I tried changing both BackColor and ForeColor but it is not working.
Code :
cmbbox.BackColor = Color.FromName("Window")
or
cmbbox.ForeColor = Color.FromName("Window")
Please help
Dear Adam:
I am making my component enable false.But I want to make it viewable.You can reffer the link.This is what exacly I want but in VB.Net : A combobox that looks decent when it is disabled
To achieve disabling combobox without fading it, first change the dropdown style of the combobox to DropDownList, Then tweak with the events to achieve the goal.
Here is a piece of code by which you can achieve the same:
Public Class Form1
Dim selectindex As Integer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ComboBox1.Items.Add("1")
ComboBox1.Items.Add("2")
ComboBox1.Items.Add("3")
ComboBox1.Items.Add("4")
selectindex = 3
ComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
ComboBox1.SelectedIndex = selectindex
End Sub
Private Sub ComboBox1_SelectionChangeCommitted(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.SelectionChangeCommitted
ComboBox1.SelectedIndex = selectindex
End Sub
End Class
Create anew form Form1 and add a combobox to the form, then add the above code to get a readonly combobox.
Have a look at this thread which has a solution for a readonly combobox and the code is all VB.NET.
A version of their code is as follows. You'll need to but it inside a class of your own which inherits System.Windows.Forms.ComboBox
Private _ReadOnly As Boolean = False
Public Property [ReadOnly]() As Boolean
Get
Return _ReadOnly
End Get
Set(ByVal Value As Boolean)
_ReadOnly = Value
End Set
End Property
Public Overrides Function PreProcessMessage(ByRef msg As Message) As Boolean
'Prevent keyboard entry if control is ReadOnly
If _ReadOnly = True Then
'Check if its a keydown message
If msg.Msg = &H100 Then
'Get the key that was pressed
Dim key As Int32 = msg.WParam.ToInt32
'Ignore navigation keys
If key = Keys.Tab Or key = Keys.Left Or key = Keys.Right Then
'Do nothing
Else
Return True
End If
End If
End If
'Call base method so delegates receive event
Return MyBase.PreProcessMessage(msg)
End Function
Protected Overrides Sub WndProc(ByRef m As Message)
'Prevent list displaying if ReadOnly
If _ReadOnly = True Then
If m.Msg = &H201 OrElse m.Msg = &H203 Then
Return
End If
End If
'Call base method so delegates receive event
MyBase.WndProc(m)
End Sub
I've been looking for the same not long ago and ended up doing the following. You may not like it, but i'll share it in case. I am using TableLayoutPanel to arrange my controls on the form and then i am swapping the positions of the desired controls.
For example I've created the following Items:
Form1 Design
TableLayoutPanel1 (two columns, three rows)
TextBox1 Read-only = True, BackColor = White
ComboBox1 Visible = False, DropDownStyle = DropDownList, FlatStyle = Popup
Button1 (named it to Change)
Button2 (named it to Done) -> Visible = False
Runtime - Screenshots
Here is my code:
Public Class Form1
Private Sub SwapControls(tlp As TableLayoutPanel, ctr1 As Control, ctr2 As Control)
Dim ctl1pos As TableLayoutPanelCellPosition = tlp.GetPositionFromControl(ctr1)
ctr1.Visible = False
tlp.SetCellPosition(ctr1, tlp.GetPositionFromControl(ctr2))
ctr2.Visible = True
tlp.SetCellPosition(ctr2, ctl1pos)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
SwapControls(TableLayoutPanel1, TextBox1, ComboBox1)
SwapControls(TableLayoutPanel1, Button1, Button2)
Label1.Select()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
SwapControls(TableLayoutPanel1, ComboBox1, TextBox1)
SwapControls(TableLayoutPanel1, Button2, Button1)
Label1.Select()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Label1.Select()
ComboBox1.SelectedIndex = 0
TextBox1.Text = ComboBox1.SelectedItem
End Sub
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
TextBox1.Text = ComboBox1.SelectedItem
End Sub
End Class