How To Auto Refresh Xml page in VB.NET? - vb.net

Trying to auto refresh xml page with timer but i see the node but the timer does not work. I post my code if you can find the problem thanks a lot in advance.
Private Sub TextBox1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim dom As New Xml.XmlDocument
dom.Load("http://69.175.13.131:8050/stats")
TextBox1.Clear()
Dim monitorid As String = String.Empty
For Each node As Xml.XmlNode In dom.SelectNodes("//SHOUTCASTSERVER/SONGTITLE")
monitorid = node.InnerText
TextBox1.Text=(monitorid)
Next
Dim timer As New Timer()
timer.Interval = 20000
AddHandler timer.Tick, AddressOf TextBox1.Refresh
timer.Start()
End Sub

The Control.Refresh method is only to redraw the control, not update its contents (unless you write code in an unexpected place to do that).
If you put the code to retrieve the data in a separate method, you can make it a bit tidier and easier to see what is happening in the code. Something like:
Public Class Form1
Dim tim As Timer
Sub ShowCurrentSongTitle(sender As Object, e As EventArgs)
Dim dom As New Xml.XmlDocument
dom.Load("http://69.175.13.131:8050/stats")
Dim node As Xml.XmlNode = dom.SelectSingleNode("//SHOUTCASTSERVER/SONGTITLE")
Dim monitorid As String = node.InnerText
TextBox1.Text = monitorid
TextBox1.SelectionStart = monitorid.Length
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ShowCurrentSongTitle(Nothing, EventArgs.Empty)
tim = New Timer With {.Interval = 20000}
AddHandler tim.Tick, AddressOf ShowCurrentSongTitle
tim.Start()
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
' tidy up...
RemoveHandler tim.Tick, AddressOf ShowCurrentSongTitle
End Sub
End Class

Related

Is there a way to simplify this code? Visual Basic Here

I'm a newbie to Visual Basic and I have this code over here that's been bugging me. I can't think of another way to simplify this. Can you please help? Thanks!:
Private Sub PictureBox_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click,
PictureBox2.Click, PictureBox3.Click, PictureBox4.Click, PictureBox5.Click, PictureBox6.Click,
PictureBox7.Click, PictureBox8.Click, PictureBox9.Click, PictureBox10.Click, PictureBox11.Click,
PictureBox12.Click, PictureBox13.Click, PictureBox14.Click, PictureBox15.Click, PictureBox16.Click,
PictureBox17.Click, PictureBox18.Click, PictureBox19.Click, PictureBox20.Click, PictureBox21.Click,
PictureBox22.Click, PictureBox23.Click, PictureBox24.Click, PictureBox25.Click, PictureBox26.Click,
PictureBox27.Click, PictureBox28.Click, PictureBox29.Click, PictureBox30.Click, PictureBox31.Click,
PictureBox32.Click, PictureBox33.Click, PictureBox34.Click, PictureBox35.Click, PictureBox36.Click,
PictureBox37.Click, PictureBox38.Click, PictureBox39.Click, PictureBox40.Click, PictureBox41.Click,
PictureBox42.Click, PictureBox43.Click, PictureBox44.Click, PictureBox45.Click, PictureBox46.Click,
PictureBox47.Click, PictureBox48.Click, PictureBox49.Click, PictureBox50.Click, PictureBox51.Click,
PictureBox52.Click, PictureBox53.Click, PictureBox54.Click, PictureBox55.Click, PictureBox56.Click,
PictureBox57.Click, PictureBox58.Click, PictureBox59.Click, PictureBox60.Click, PictureBox61.Click,
PictureBox62.Click, PictureBox63.Click, PictureBox64.Click
...............
............... (stuff is down here.)
...............
...............
End Sub
You will need to store the lists in a collection of some sort. This can either be an array or a List(Of PictureBox) or if all of the controls have the same parent you can simply leverage the Controls property.
Once you have the collection in place, you will need to iterate over collection and use AddHandler to reference. Inside the referenced method, you would get the sender, and convert it to a PictureBox.
Here is an example assuming all the PictureBox controls are on the Form:
Private Sub Form1_Load(sender As Object, e As EventArgs)
For Each pb In Controls.OfType(Of PictureBox)()
AddHandler pb.Click, AddressOf pb_Click
Next
End Sub
Private Sub pb_Click(sender As Object, e As EventArgs)
Dim pb = DirectCast(sender, PictureBox)
' pb is the control that was clicked
End Sub
Here's how to build a list of the pictureboxes, with them "in order", assuming they are already on the form:
Public Class Form1
Private PBs As New List(Of PictureBox)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For i As Integer = 1 To 64
Dim ctlName As String = "PictureBox" & i
Dim ctl As Control = Me.Controls.Find(ctlName, True).FirstOrDefault
If Not IsNothing(ctl) AndAlso TypeOf ctl Is PictureBox Then
Dim pb As PictureBox = DirectCast(ctl, PictureBox)
AddHandler pb.Click, AddressOf PB_Click
PBs.Add(pb)
Else
MessageBox.Show("Unable to find " & ctlName)
End If
Next
End Sub
Private Sub PB_Click(sender As Object, e As EventArgs)
Dim pb As PictureBox = DirectCast(sender, PictureBox)
' ... do something with pb ...
End Sub
End Class
From the comments:
Wait a minute, how do I do For Each pb In Controls.OfType(Of
PictureBox)() AddHandler pb.Click, AddressOf pb_Click Next But for a
List(Of Picturebox) named "Formula"?
For Each pb As PictureBox in Formula
AddHandler pb.Click, AddressOf pb_Click
Next
Here's what you code produces after turning on the BorderStyle:

How do i refresh WebBrowser1 whitout flickering on VB.NET?

I call my page every 20 seconds but when i call my page i see a flash. Is it possible to avoid the flickering when the page load?
Private Sub WebBrowser1_load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
WebBrowser1.Navigate(New Uri("http://metalrockpopradio.caramania.com/tuneefy4.php"))
Dim timer As New Timer()
timer.Interval = 20000
AddHandler timer.Tick, AddressOf WebBrowser1.Refresh
timer.Start()
You can do something like this:
Create a Form (here called Form1)
add a PictureBox (here, called PictureBox1) to it
set the PictureBox size to what you want and set its SizeMode = Zoom
paste the following code inside the Form's code partial file (F7 on the Form)
Imports System.Net
Imports System.Windows.Forms
Public Class Form1
Dim timer As System.Windows.Forms.Timer
Private client As WebClient = New WebClient()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
RefreshImage(Nothing, Nothing)
timer = New System.Windows.Forms.Timer()
AddHandler timer.Tick, AddressOf Me.RefreshImage
timer.Interval = 5000
timer.Start()
End Sub
Protected Sub RefreshImage(sender As Object, e As EventArgs)
Dim HttpResource As String = client.DownloadString("http://metalrockpopradio.caramania.com/tuneefy4.php")
Dim ParseStart As Integer = HttpResource.IndexOf("=") + 2
HttpResource = HttpResource.Substring(ParseStart, HttpResource.LastIndexOf(ChrW(34)) - ParseStart)
If PictureBox1.Image IsNot Nothing Then PictureBox1.Image.Dispose()
PictureBox1.Load(HttpResource)
End Sub
Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
client.Dispose()
timer.Dispose()
End Sub
End Class
Have two of them. When the new reload is done, show the new control and hide the old.
Alternatively, use AJAX or similar on your page to reload content.

Change the color of a button(s) for a duration of time

I have a small VB.net app that has a LOT of buttons. I need to change the back color of the buttons when they are clicked and then set it back to its original color after a duration of 10 seconds. I am struggling with either using a timer or the time process both of which have their own issues.
Any ideas to make this work and work efficiently?
Code:
Private Sub MyButtons_Click(sender As Object, e As EventArgs) _
Handles Button1.Click,
Button2.Click
Dim myButton = DirectCast(sender, Button)
MakeCall()
myButton.BackColor = Color.Green
'TurnOnActiveCallCOLOR.Enabled = True
For i As Integer = 0 To 10000 - 1
Threading.Thread.Sleep(10000)
Next
myButton.BackColor = Color.FromArgb(64, 64, 64)
End Sub
Here is an example of using a Windows Forms Timer to accomplish what you need:
Private MyButton As Button
Private Sub MyButtons_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click
MyButton = DirectCast(sender, Button)
MyButton.BackColor = Color.Green
Timer1.Enabled = True
MakeCall()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
MyButton.BackColor = Color.FromArgb(64, 64, 64)
Timer1.Enabled = False
End Sub
To handle an arbitrary number of buttons, you could have something like this:
Public Class Form1
Dim buttonTimers As New Dictionary(Of Control, ButtonTimer)
Class ButtonTimer
Property Timeout As Integer = 2000
Property Target As Control
Property ActiveColor As Color = Color.Green
Property DefaultColor As Color = Color.FromArgb(64, 64, 64)
Private tim As Timer
Sub TimTick(sender As Object, e As EventArgs)
tim.Stop()
Target.BackColor = DefaultColor
End Sub
Sub New()
' empty constructor
End Sub
Sub New(target As Control)
Me.Target = target
Me.Target.BackColor = Me.ActiveColor
tim = New Timer With {.Interval = Timeout}
AddHandler tim.Tick, AddressOf TimTick
tim.Start()
End Sub
Sub Restart()
Target.BackColor = Me.ActiveColor
If tim IsNot Nothing Then
tim.Stop()
tim.Start()
End If
End Sub
Public Sub DisposeOfTimer()
If tim IsNot Nothing Then
tim.Stop()
RemoveHandler tim.Tick, AddressOf TimTick
tim.Dispose()
End If
End Sub
End Class
Private Sub Button_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click
Dim myButton = DirectCast(sender, Button)
'MakeCall()
If buttonTimers.ContainsKey(myButton) Then
buttonTimers(myButton).Restart()
Else
buttonTimers.Add(myButton, New ButtonTimer(myButton))
End If
End Sub
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
For Each x In buttonTimers
x.Value.DisposeOfTimer()
Next
End Sub
End Class
If a button is clicked again before the timeout, the time is restarted.
You can add other constructors if you want to have a different timeout/colours for different buttons.
The MyBase.FormClosing code should be included in your form closing handler (if there is one) so that the timers are cleaned up properly.
I expect it would be tidier overall to make your own custom button class which inherits from Button, so you might want to investigate doing that. (How to: Inherit from Existing Windows Forms Controls.)
asynh and await if you don't want use timer. Simple method using task.delay
Private Async Sub ButtonClick(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click, Button3.Click, Button4.Click
DirectCast(sender, Button).BackColor = Color.Red 'after click setcolor to red
Await setColorAfterDelay(sender) 'Add this comand on button click and don't forget add asynh before sub in this method
End Sub
Public Async Function setColorAfterDelay(sender As Object) As Task
Await Task.Delay(1000) ''Milisecound how long you wana dealey
DirectCast(sender, Button).BackColor = Color.White 'and set colorto white
End Function
With the use of lambda expressions (and a lookup table if you want to interact with it further) you can do this pretty easily:
'Lookup table for if you want to be able to interact with the timers even more.
Dim ButtonTimers As New Dictionary(Of Button, Timer)
Private Sub MyButtons_Click(sender As Object, e As EventArgs) _
Handles Button1.Click, Button2.Click
MakeCall()
Dim myButton = DirectCast(sender, Button)
myButton.BackColor = Color.Green
'If a timer already exists for the button, restart it.
Dim existingTimer As Timer = Nothing
If ButtonTimers.TryGetValue(myButton, existingTimer) Then
existingTimer.Stop()
existingTimer.Start()
Return 'Do not execute the rest of the code.
End If
'Create the timer and set its Interval to 10000 ms (10 seconds).
Dim buttonTimer As New Timer() With {.Interval = 10000}
'Add a handler to its Tick event.
AddHandler buttonTimer.Tick, _
Sub(tsender As Object, te As EventArgs)
myButton.BackColor = Color.FromArgb(64, 64, 64)
'Dispose timer and remove from lookup table.
ButtonTimers.Remove(myButton)
buttonTimer.Stop()
buttonTimer.Dispose()
End Sub
ButtonTimers.Add(myButton, buttonTimer)
buttonTimer.Start()
End Sub
If you want to interact with a button's timer (if one exists) you can do:
Dim buttonTimer As Timer = Nothing
If ButtonTimers.TryGetValue(yourButtonHere) Then
'Do something with buttonTimer...
End If
This could probably be done better by dynamically creating timer controls so each button has it's own timer but here is what I came up with.
Oh, an set your timer to 1000 interval and enabled to 'False'.
Public Class Form1
Dim T1 As Integer = 0
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
T1 = T1 + 1
If T1 = 10 Then
For Each button In Controls
button.backcolor = Color.FromArgb(225, 225, 225)
Next
Timer1.Stop()
T1 = 0
End If
Me.Text = T1
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Button1.BackColor = Color.Red
Timer1.Start()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Button2.BackColor = Color.Orange
Timer1.Start()
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Button3.BackColor = Color.Yellow
Timer1.Start()
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Button4.BackColor = Color.Green
Timer1.Start()
End Sub
Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
Button5.BackColor = Color.Blue
Timer1.Start()
End Sub
End Class

Late Binding Issue with BackgroundWorker in VB.Net

I am running a BackgroundWorker, and want to report its progress. In the example below I create a test list which the BackgroundWorker then iterates through. The problem lies in the line 'sender.ReportProgress(i)'. If I have Option Strict on, it does not like my use of 'i' due to Late Binding issues. Is there any alternative way to code this and avoid that issue?
Public Class Form1
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
' Configuring for Background Workers
Control.CheckForIllegalCrossThreadCalls = False
Dim MyList As New List(Of String)
For a As Integer = 0 To 100
MyList.Add(CStr(a))
Next
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim bgw As New System.ComponentModel.BackgroundWorker
bgw.WorkerReportsProgress = True
bgw.WorkerSupportsCancellation = True
AddHandler bgw.DoWork, AddressOf bgw_DoWork
' I create a BackgroundWorker here rather than add one in the toolbox so that I can specify the Handler and use different Handler routines for different part of a large program.
Button1.Enabled = False
Dim progress As New Progress(bgw)
progress.ShowDialog()
Button1.Enabled = True
End Sub
Private Sub bgw_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs)
For i = 0 To MyList.Count -1
Label1.Text = MyList(i)
sender.ReportProgress(i)
System.Threading.Thread.Sleep(200)
Label1.Refresh()
Next
End Sub
End Class
Public Class Progress
Private WithEvents _BGW As System.ComponentModel.BackgroundWorker
Public Sub New(ByVal BGW As System.ComponentModel.BackgroundWorker)
_BGW = BGW
InitializeComponent()
End Sub
Private Sub frmProgress_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown
If Not IsNothing(_BGW) Then
_BGW.RunWorkerAsync()
End If
End Sub
Private Sub _BGW_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles _BGW.ProgressChanged
ProgressBar1.Value = e.ProgressPercentage
Label1.Text = e.ProgressPercentage
End Sub
Private Sub _BGW_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles _BGW.RunWorkerCompleted
Me.Close()
End Sub
End Class
CType(sender, BackgroundWorker).ReportProgress(i)
Also, if you want to do multiple actions with it, then create a local reference variable like this:
Private Sub bgw_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs)
Dim bgw As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
' ... now you can use "bgw" multiple times below instead of casting each time ...
For i = 0 To MyList.Count -1
Label1.Text = MyList(i)
bgw.ReportProgress(i)
bgw.SomethingElse()
bgw.MoreStuff()
System.Threading.Thread.Sleep(200)
Label1.Refresh()
Next
End Sub
Obviously this isn't necessary in your case, just an FYI...

Deleting all Timers VB.net

I create timers within a class
Dim timer As New Timer
timer.Enabled = True
timer.Interval = 1000
timer.Tag = "TimeslipTimer_" & timeslip.id
AddHandler timer.Tick, AddressOf GlobalTimerTick
timer.Start()
The problem i have is how can I delete those if I needed?
At the moment I was looking to add timers to a list, similar to below, but i didnt work out
dim timers as new list(of Timer)
For Each c As Timer In Timers
c.Dispose()
Timers.Remove(c)
Next
When removing from a list the list must be accessed in reverse order. Also remember to remove the handler.
Public Class Form1
Private WithEvents timer As Timer
Private timers As New List(Of Timer)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
timer = New Timer
timers.Add(timer)
timer.Enabled = True
timer.Interval = 1000
'timer.Tag = "TimeslipTimer_" & timeslip.id
AddHandler timer.Tick, AddressOf GlobalTimerTick
timer.Start()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
For x As Integer = timers.Count - 1 To 0 Step -1
Dim t As Timer = timers(x)
RemoveHandler t.Tick, AddressOf GlobalTimerTick
t.Stop()
t.Dispose()
timers.RemoveAt(x)
Next
End Sub
Private Sub GlobalTimerTick(sender As Object, e As EventArgs)
Debug.WriteLine("TICK")
End Sub
End Class