How To: Colour Flash TextBox background?

  • Thread starter Thread starter Mr. B
  • Start date Start date
M

Mr. B

While at first this may seem a simple tast, it has plagued me for a while...

What I want to do is to have the background colour of something like a TextBox
to change from (say) White to Yellow to White to Yellow and then back to White
in about 1 second or so.

This is to create something like a 'flash' (or a Pulse) for when a User clicks
on 1 of 4 Radio Buttons (which change the Text in the TextBox). So in other
words, to get the User's attention that the Text has Changed. Popup boxes are
a pain, so I don't want to go there (ie: they may click several RadioButtons).

I've tried something simple like the following to Test this out. But you do
not 'see' any background change happening. So obvious, I'm missing something
fundamental here:

Private Sub rbASME1_CheckedChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles rbASME1.CheckedChanged
pltPrefx = "a"
txbScrName.Text = pltPrefx & pltTitle & pltType
Dim TimCtr, TimX As Integer
For TimX = 1 To 4
If TimX = 1 Then txbScrName.BackColor = Color.Yellow
If TimX = 2 Then txbScrName.BackColor = Color.White
If TimX = 3 Then txbScrName.BackColor = Color.Yellow
If TimX = 4 Then txbScrName.BackColor = Color.White
For TimCtr = 0 To 200000
Next 'timx
Next ' timctr
txbScrName.BackColor = Color.White
End Sub

Anyone else done something similar? I think I tried a Timer Control a while
back also without success...

Regards,

Bruce
 
Mr. B,

While this isn't exactly what you want, it is similar to something I have done.
I just threw this sample together quickly with a Form, TextBox (TextBox1), and a
Button (Button1).
There very well may be a better / safer way, but I am confident it is better
than what you are trying to do.

'------------------------------------------------------------
'Will Flash the background Yellow of any control that supports the BackColor
property
'Note: No error checking implemented in this sample.
Private Sub FlashBackground(ByVal control As System.Windows.Forms.Control)
Dim origColor As System.Drawing.Color

'Store the original Background color of the control so we can restore it
origColor = control.BackColor

With control
'Set the BackColor to Yellow
.BackColor = System.Drawing.Color.Yellow
'Tell the control to redraw with the new setting
.Update()
'Wait for a short time. If we don't do this, then the update
' would be so quick we wouldn't see it.
'FYI, this will suspend the whole current GUI thread, which in this
' case is what we want.
Threading.Thread.Sleep(100)
'Restore the original BackColor
.BackColor = origColor
'Tell the control to redraw with the new setting
.Update()
End With

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
FlashBackground(TextBox1)
End Sub

'------------------------------------------------------------

Gerald
 
First off, you can make the code smaller by using the Mod statement,
Secondly, don't use loops for pauses (what if someone has a 186? or a
1millionzillion86?)
Private Sub rbASME1_CheckedChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles rbASME1.CheckedChanged
pltPrefx = "a"
txbScrName.Text = pltPrefx & pltTitle & pltType
Dim TimCtr, TimX As Integer
For TimX = 1 To 4
If TimX = 1 Then txbScrName.BackColor = Color.Yellow
If TimX = 2 Then txbScrName.BackColor = Color.White
If TimX = 3 Then txbScrName.BackColor = Color.Yellow
If TimX = 4 Then txbScrName.BackColor = Color.White
For TimCtr = 0 To 200000
Next 'timx
Next ' timctr
txbScrName.BackColor = Color.White
End Sub

' ///
For TimX = 1 To 4
txtScrName.BackColor = CType(IIf((TimX Mod 2) = 0, Color.White,
Color.Yellow), System.Drawing.Color)
System.Threading.Thread.Sleep(1000)
Next

txtScrName.BackColor = Color.White
' ///

Untested, but give that a try :)

--
HTH,
-- Tom Spink, Über Geek

Woe be the day VBC.EXE says, "OrElse what?"

Please respond to the newsgroup,
so all can benefit
 
Shoot... something that just crossed my mind is that you may need an
Application.DoEvents() in there to repaint the textbox.... If it doesn't
work first time, add this line before the
System.Threading.Thread.Sleep(1000) line:

Application.DoEvents()

--
HTH,
-- Tom Spink, Über Geek

Woe be the day VBC.EXE says, "OrElse what?"

Please respond to the newsgroup,
so all can benefit
 
Wrap the timer in a new class and overload the start to pass the control
you wan to affect. Then use a control property on the wrapped class to store
the reference to the control being processed so that your handler can alter
the right textbox. When your done, just stop the timer

--

OHM ( Terry Burns )
. . . One-Handed-Man . . .

Time flies when you don't know what you're doing
 
There ya go MR. B., a more comprehensive answer ! - (Tested I Might Add )
----------------------------------------------------------------------------
-

Public Class xTimer
Inherits Timer

Public Sub New()
MyBase.New()
End Sub

Private m_control As Control
Public Property xControl() As Control
Get
Return m_control
End Get
Set(ByVal Value As Control)
m_control = Value
End Set
End Property

End Class


// FORM
Private WithEvents MyTimer As New xTimer
Private FlipBackColor As Boolean = True

Private Sub MyTimer_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyTimer.Tick
Dim tim As xTimer = DirectCast(sender, xTimer)
Dim xText As TextBox
Try
xText = tim.xControl()
If FlipBackColor Then
xText.BackColor = Color.Red
FlipBackColor = False
Else
xText.BackColor = Color.White
FlipBackColor = True
End If
Catch ex As Exception
'TODO:
End Try
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Try
MyTimer.xControl = TextBox1
MyTimer.Interval = 250
MyTimer.Start()
Catch ex As Exception
'TODO:
End Try

End Sub

--

OHM ( Terry Burns )
. . . One-Handed-Man . . .

Time flies when you don't know what you're doing
 
Ok, here is an update that will do what you want put into your context.
See previous post for original comments.

'------------------------------------------------------------
'Will Flash the background Yellow of any control that supports
' the BackColor property
Private Sub FlashBackground(ByVal control As System.Windows.Forms.Control)
Dim origColor As System.Drawing.Color

Try
'Store the original Background color of the control so we can
restore it
origColor = control.BackColor
With control

For flashCount As Integer = 1 To 2
.BackColor = System.Drawing.Color.Yellow
.Update()
Threading.Thread.Sleep(200)
.BackColor = System.Drawing.Color.White
'If your original BackColor is not White or Yellow already,
' then maybe try the following, as it is a little prettier
'.BackColor = origColor
.Update()
Threading.Thread.Sleep(200)
Next flashCount

'Not necessary if you use the origColor above
.BackColor = origColor
.Update()
End With
Catch ex As Exception
'TODO:
End Try

End Sub


Private Sub rbASME1_CheckedChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles rbASME1.CheckedChanged

pltPrefx = "a"
txbScrName.Text = pltPrefx & pltTitle & pltType

FlashBackground(txbScrName)

End Sub

'------------------------------------------------------------

Of course you could make the flash interval, color, etc. anything you want.
You could even pass them in as parameters to the Sub for complete control.

FYI: One Handed Man's solution has the benefit of you being able to just
set it off and let it run for continual flashing if desired.

Gerald
 
* "One Handed Man \( OHM - Terry Burns \) said:
Public Class xTimer
Inherits Timer

Public Sub New()
MyBase.New()
End Sub

Private m_control As Control
Public Property xControl() As Control
Get
Return m_control
End Get
Set(ByVal Value As Control)
m_control = Value
End Set
End Property

End Class


// FORM
Private WithEvents MyTimer As New xTimer
Private FlipBackColor As Boolean = True

Private Sub MyTimer_Tick(ByVal sender As Object, ByVal e As
System.EventArgs) Handles MyTimer.Tick
Dim tim As xTimer = DirectCast(sender, xTimer)
Dim xText As TextBox
Try
xText = tim.xControl()
If FlipBackColor Then
xText.BackColor = Color.Red
FlipBackColor = False
Else
xText.BackColor = Color.White
FlipBackColor = True
End If
Catch ex As Exception
'TODO:
End Try

What exceptions are you expecting here?

BTW: I don't see any advantages in adding the reference to the control to the timer, and then placing the
'Tick' event handler to the form. Instead, I would extend the textbox,
instantiate the timer in the extended textbox to keep the stuff outside
the form's implementation (better encapsulation).
 
No. Many textBoxes, 1 timer

--

OHM ( Terry Burns )
. . . One-Handed-Man . . .

Time flies when you don't know what you're doing

Herfried K. Wagner said:
What exceptions are you expecting here?

BTW: I don't see any advantages in adding the reference to the control to
the timer, and then placing the
 
I normally would not have put the Try/Catch here, but when I was debugging I
was getting some exceptions.

--

OHM ( Terry Burns )
. . . One-Handed-Man . . .

Time flies when you don't know what you're doing

Herfried K. Wagner said:
What exceptions are you expecting here?

BTW: I don't see any advantages in adding the reference to the control to
the timer, and then placing the
 
With Deft Fingers, "One Handed Man \( OHM - Terry Burns \)"
There ya go MR. B., a more comprehensive answer ! - (Tested I Might Add )
----------------------------------------------------------------------------

As always... Thanks! (seems like I'm doing that to you alot these days) (:

Regards,

Bruce
 
No problem. Its all part of the learning process. Herfied pointed out that
the TextBox could have been extended and a timer instantiated in each one.
This is also a possibility. However, I chose not to do it this way to reduce
resources, with H's suggestion you should create a user control something
like this.

This actually works but a little more effort needs to go into it so when you
stop the flash, you set the color to white, and also you need to set the
m_FlashRate of the Timer in the constructor so it allways initialises to a
standard acceptable rate, even though you can change it, or you could
overload the constructor and pass this valiable in that way, up 2 u.

HTH

Public Class MyTextBox
Inherits System.Windows.Forms.UserControl

Private FlipColor As Boolean = True
Private m_FlashState As Boolean = False
Private m_FlashRate As Int32 = 250

Public Property FlashRate() As Int32
Get
Return m_FlashRate
End Get
Set(ByVal Value As Int32)
m_FlashRate = Value
Me.Timer1.Interval = m_FlashRate
End Set
End Property

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Timer1.Tick

If FlipColor Then
Me.TextBox1.BackColor = Color.Red
FlipColor = False
Else
Me.TextBox1.BackColor = Color.Aquamarine
FlipColor = True
End If
End Sub

Public Property Flash() As Boolean
Get
Return m_FlashState
End Get
Set(ByVal Value As Boolean)
m_FlashState = Value
If Value Then
Me.Timer1.Start()
Else
Me.Timer1.Stop()
End If
End Set
End Property

--

OHM ( Terry Burns )
. . . One-Handed-Man . . .

Time flies when you don't know what you're doing
 
Back
Top