I'm currently following the Head First C# but every so often I play around on my own. I ran into a situation that I'm unable to solve. I want to change this.BackColor
from MediumBlue to step through green 0 - 255 and back to console with a button I/O. The issue is that I can't get the color to stop stepping and go back to MediumBlue.
private void btnClr_Click(object sender, EventArgs e)
{
int fClr = 0;
while (Visible)
{
if (fClr == 0)
{
fClr++;
for (int nBackClr = 0; nBackClr < 255 && Visible; nBackClr++)
{
this.BackColor = Color.FromArgb(nBackClr, 255 - nBackClr, nBackClr);
Application.DoEvents();
Thread.Sleep(2);
}
for (int z = 255; z >= 0 && Visible; z--)
{
this.BackColor = Color.FromArgb(z, 255 - z, z);
Application.DoEvents();
Thread.Sleep(2);
}
}
else
{
fClr--;
this.BackColor = Color.MediumBlue;
Application.DoEvents();
Thread.Sleep(1);
}
}
}
Another thing I'd love to know is how to get the BackColor
to go through the ENTIRE color palette.
EDIT: S/n After applying JABFreeware's solution. I added a breakpoint to see what was going on and fClr
gets the value of 1 when I first click btnClr_Click
. However when I click it again fClr
gets 0 but then immediately gets 1 again. Not sure if this has to do with the while (Visible)
. ..Head Scratcher..
One of your problems is that int fClr = 0;
is inside the button click event handler so every time they click the button, its reset to 0. Move the variable outside the click event.
Like this:
int fClr = 0;
private void btnClr_Click(object sender, EventArgs e)
{
while (Visible)
{
if (fClr == 0)
{
fClr++;
for (int nBackClr = 0; nBackClr < 255 && Visible; nBackClr++)
{
this.BackColor = Color.FromArgb(nBackClr, 255 - nBackClr, nBackClr);
Application.DoEvents();
Thread.Sleep(2);
}
for (int z = 255; z >= 0 && Visible; z--)
{
this.BackColor = Color.FromArgb(z, 255 - z, z);
Application.DoEvents();
Thread.Sleep(2);
}
}
else
{
fClr--;
this.BackColor = Color.MediumBlue;
Application.DoEvents();
Thread.Sleep(1);
}
}
}
It is easier to use a timer. That way your UI will remain responsive without using DoEvents
.
const int ColorStep = 16;
private Timer _timer;
private int _r, _g, _b;
public frmRotateColors()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
_r = 0;
_g = 0;
_b = 0;
// Start the timer
_timer = new Timer { Interval = 10 };
_timer.Tick += Timer_Tick;
_timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
if (_b >= 256) {
_timer.Dispose(); // Stop the timer.
this.BackColor = SystemColors.Control; // Reset the background color.
} else {
this.BackColor = Color.FromArgb(_r, _g, _b);
// Get next color
_r += ColorStep;
if (_r >= 256) {
_r = 0;
_g += ColorStep;
if (_g >= 256) {
_g = 0;
_b += ColorStep;
}
}
}
}
Here I rotate through all the colors by increasing the red color. If I am out of range of red colors (0 - 255) I reset the red color and increase the green color. If the green color range is exceeded I reset the green color and increase the blue color. Finally, if the blue color range is exceeded I terminate the process.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.