c# colour change loop - c#

I am trying to make an 'automatic colour change loop' in other words when someone's mouse hovers over a label, it changes colour in fast repetition, say, 300 microseconds.
private void label1_MouseHover(object sender, EventArgs e)
{
while (true)
{
Random color = new Random();
Color randomColor = Color.FromArgb(color.Next(255), color.Next(255), color.Next(255)); label1.ForeColor = randomColor;
return;
}
}
The issue is in the loop, or should I say lack thereof, I was under the presumption that the while(true) was in itself a loop there for if I kept the mouse in same place, as long as it was over the label it would act, but it only acts once, in simpler terms, I have to hover over it, then leave the area, then hover again, to get it to change colour twice, the ideal is that I can have it always changing colour, so I don't have to hover, but I can't think of a way to do that, since I need the while loop. any ideas for that second part is appreciated but not necessary :)

Okay, so thanks to the guys that realised I am an idiot :3
For anyone else who may want / need the code.
at the beginning of the form:
public Form2()
{
InitializeComponent();
notifyIcon1.Visible = true;
timer2.Start();
}
private void timer2_Tick(object sender, EventArgs e)
{
timer2.Interval = 100;
timer2.Enabled = true;
timer2.Tick += changer;
}
void changer (object sender, EventArgs e)
{
Random color = new Random();
Color randomColor = Color.FromArgb(color.Next(255), color.Next(255), color.Next(255));
label1.ForeColor = randomColor;
}
Now add these, btw, I am aware that I am still issuing a new random every time, if you want to edit that, go ahead, but it works for me, quite nicely, so I am going to keep it that way.

Related

Need help on my alarm program

I want to make an alarm program where the user is asked to choose the time and the day of the week. If the user choose the day, the text in the label will be in bold. I am having trouble to pass the list from button2_click to Timer_Elapsed. The program worked well except when i pressed the button, the functions in Timer_Elapsed wont work.
List<string> list = new List<string>();
private void Form1_Load(object sender, EventArgs e)
{
timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += Timer_Elapsed;
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
DateTime currentTime = DateTime.Now;
DateTime userTime = dateTimePicker1.Value;
foreach(string _list in list)
{
if(currentTime.DayOfWeek.Equals(_list) && currentTime.Hour==userTime.Hour && currentTime.Minute==userTime.Minute && currentTime.Second == userTime.Second)
{
SoundPlayer player = new SoundPlayer();
player.SoundLocation = #"C:\Users\Andrew\Music\test1.wav";
player.PlayLooping();
if(MessageBox.Show("","It's Time!", MessageBoxButtons.OK)==DialogResult.OK)
{
player.Stop();
}
}
}
}
private void button2_Click(object sender, EventArgs e)
{
timer.Start();
if (label3.Font.Bold)
{
list.Add("Monday");
}
if (label4.Font.Bold)
{
list.Add("Tuesday");
}
if (label5.Font.Bold)
{
list.Add("Wednesday");
}
if (label6.Font.Bold)
{
list.Add("Thursday");
}
if (label7.Font.Bold)
{
list.Add("Friday");
}
if (label8.Font.Bold)
{
list.Add("Saturday");
}
if (label9.Font.Bold)
{
list.Add("Sunday");
}
foreach (string _list in list)
{
label10.Text = label10.Text + _list + " ";
}
label10.Visible = true;
}
private void label3_Click(object sender, EventArgs e)
{
label3.Font = new Font(label3.Font, FontStyle.Bold);
}
private void label4_Click(object sender, EventArgs e)
{
label4.Font = new Font(label4.Font, FontStyle.Bold);
}
private void label5_Click(object sender, EventArgs e)
{
label5.Font = new Font(label5.Font, FontStyle.Bold);
}
private void label6_Click(object sender, EventArgs e)
{
label6.Font = new Font(label6.Font, FontStyle.Bold);
}
private void label7_Click(object sender, EventArgs e)
{
label7.Font = new Font(label7.Font, FontStyle.Bold);
}
private void label8_Click(object sender, EventArgs e)
{
label8.Font = new Font(label8.Font, FontStyle.Bold);
}
private void label9_Click(object sender, EventArgs e)
{
label9.Font = new Font(label9.Font, FontStyle.Bold);
}
private void button1_Click(object sender, EventArgs e)
{
label3.Font = new Font(label3.Font, FontStyle.Regular);
label4.Font = new Font(label4.Font, FontStyle.Regular);
label5.Font = new Font(label5.Font, FontStyle.Regular);
label6.Font = new Font(label6.Font, FontStyle.Regular);
label7.Font = new Font(label7.Font, FontStyle.Regular);
label8.Font = new Font(label8.Font, FontStyle.Regular);
label9.Font = new Font(label9.Font, FontStyle.Regular);
}
In if statement, You are comparing DayOfWeek Enum value to string: currentTime.DayOfWeek.Equals(_list) this will be always false. Change with this:
currentTime.DayOfWeek.ToString().Equals(_list)
Just like Giorgi said, you are comparing the Enum to a string. You would need to ToString() it before.
As for the rest of your code, here are a couple pointers to make it better overall, since you seem to be beginning. If you don't understand one of the tips, try to read about it. Understanding why it is better is much more important than just blindly changing it. Most of the tips are extremely simplified pointers, and the level is pretty basic too.
Better functionality:
Make a label click either turn it bold or turn it back to normal, depending on it's current state. This will allow a user to remove one of them easily. This will make button1 irrelevant too.
label3.Font = new Font(label3.Font, label3.Font.Bold ? FontStyle.Regular : FontStyle.Bold);
Allow button2 to deactivate the alarm, by clicking it again.
Do not hard-code the path to your sound, instead include it as a ressource, or just put it in the folder with the executable and use a relative path
Nobody needs an alarm up to the second. Make the timer Interval about 30 seconds or so (to avoid millisecond errors), and compare up to the minute.
Don't start the alarm if it is already ringing
Safeguard your dangerous code, like finding the sound file, either by checking it exists beforehand (and reacting appropriately) or with a simple try catch, so that your program doesn't crash at critical moments.
Better code:
Add Enum values (from DayofWeek) to your list, then you will not need to convert anything to compare them
Name your form controls and variables better, so that their use is obvious from the name. "label3", "button2", "list" are horrible names for variables, especially global ones.
Considering the fact that you don't give any other option than "OK" when it rings, don't test the dialog response at all.
player.PlayLooping();
MessageBox.Show("", "It's time!");
player.Stop();
Use the same function for all label clicks, like this:
private void labelDay_Click(object sender, EventArgs e)
{
Label currentLbl = (label) sender;
currentLbl.Font = new Font(currentLbl.Font, currentLbl.Font.Bold ? FontStyle.Regular : FontStyle.Bold);
}
Hold all your labels in an array, so that you can loop through them in the button clicks
Compare the time using a difference, so that you don't have to compare days, then hours, then minutes, etc. A DateTime can easily be compared in one operation.
WinForms has a timer component that you can use from the editor
Dispose of your SoundPlayer when you're done with it, or re-use it. C# takes care of that for you behind the scenes, but that is a very good habit to learn in programming in general
That should be a good start to learning a few very useful things about C# and WinForms, and starting to use better code practices. This is in no way an exhaustive list of everything that could be improved, but since you probably don't plan on ever turning this program into a piece of software used by the whole world, this should be a good stepping stone for you.

How can I delay an animation without using System.Threading.Thread.Sleep()

I want to move my text up, but if I use System.Threading.Thread.Sleep() my app gets stuck. I think that the using a Timer is a good way to solve it but pls show me how. I was trying to use Animate() also, but I didn't solve it by this way.
for (int i = 0; i < 30; i+=2)
{
Brush snizovaniViditelnosti = new SolidBrush(Color.FromArgb(0+i*8, 0+i*8,0+i*8));
g.DrawString("+1", fontPridaniMaterialu, snizovaniViditelnosti, MousePosition.X, MousePosition.Y - i);
System.Threading.Thread.Sleep(30);
//ImageAnimator.Animate()
Timer d = new Timer();
d.Interval = 55;
Refresh();
}
It's suppose to work that I click on some button and then appears text - "+1" and it will be moving up with reducing opacity. Finally it will disappear.
Grab Timer and Button from toolbox.
Then select timer and go to events section in properties window. Double click Tick event. Apply your logic for moving text.
For button you need to use click event.
Sample code:
private void timer1_Tick (object sender, EventArgs e)
{
button1.Location = new Point (button1.Location.X + 1, button1.Location.Y);
}
private void button1_Click (object sender, EventArgs e)
{
timer1.Start ();
}
You will have to create a Timer out of your for loop and replace the loop by a Tick event. At the moment you are re-creating the Timer in every loop iteration. Put it as a component to your control, like this:
// Timer Interval is set to 0,5 second
private Timer _timer = new Timer { Interval = 500 };
And adding also the following fields to your control for
private int _index = 0;
private int _maxIndex = 30;
After this adding a delegate to the Tick event, which will moving up your text a ttle bit on every tick.
this._timer.Tick += delegate
{
if (this._index < this._maxIndex)
{
var alphaValue = 255 - this._index * 8;
Brush snizovaniViditelnosti = new SolidBrush(Color.FromArgb(alphaValue, 255, 255, 255));
g.DrawString("+1", fontPridaniMaterialu, snizovaniViditelnosti, MousePosition.X, MousePosition.Y - this._index);
Refresh();
this._index++;
}
else
{
this._timer.Stop();
}
};
If you only want to reduce opacity, reduce the alpha value and leave the color - as shown in the example above.
And wire this to your Button click event
private void Button_Click(object sender, EventArgs e)
{
this._timer.Start();
}
Hint: This is a quick solution for only one item. If you want to do this for more than one item you may add a class to your code containing the text, the Timer and the current and maxIndex.
I guess you are using winforms.
To avoid flickering while re-drawing your UI. You should activate double buffering.
See more information about Handling and Raising Events
As #apocalypse suggested in his answer. It will be better to setup a fix start location for your text to move up.

Set a limit on the amount of numbers that can be entered into a "masked textbox"

I am still learning the basics with C# and i am having some trouble. I have been searching the internet for about 3 hours now for an answer on how to set a limit on the amount of characters(in this case it will be limited to a 3 digit integer) a user can enter into a "masked Textbox". I have come across a few different kinds of code, but when i run the program i am still able to enter in as many characters i want. If there is no argument i can add on to do this (meaning i will have to set a loop to check every time) please let me know. I am struggling to learn. Here is the small piece of code that i am attempting to work on.
private void mtbMales_MouseClick(object sender, EventArgs e)
{
mtbMales.Text = "";
mtbMales.SelectionStart = 0;
mtbMales.MaxLength = 3;
mtbMales.Mask = "000";
}
private void mtbFemales_MouseClick(object sender, EventArgs e)
{
mtbFemales.Text = "";
mtbFemales.SelectionStart = 0;
mtbFemales.MaxLength=3;
mtbFemales.Mask = "000";
}
Just set the Mask Property of the masked text box to OOO in the design mode, and you're done.
If you want to set it programmically, set it in the form load event (Double click the form in Design mode)
private void Form1_Load(object sender, EventArgs e)
{
mtbMales.MaxLength = 3;
mtbMales.Mask = "000";
}

Click and hold on textblock while dragging mouse to make value bigger/smaller

I want the same thing as in this Question:
Click and hold on button while dragging mouse to make value bigger/smaller
The only answer there was the Slider but that was not what the Question asker meant. And nor what i meant.
I know something like this is possible in iOs, but i want to use it in a windows app, but i cant seem to figure out how to do it.
I tried doing it with pointerpressed, pointerrelease and pointermoved. And it worked in a way but i stops working when you get out of the range from the textblock so it does only work when you drag on the textblock itself, and i want to do it so that you can drag over the whole screen if necessary.
this is what i have so far:
private void TextBlock_PointerPressed(object sender, PointerRoutedEventArgs e)
{
ystart = e.GetCurrentPoint(this).Position.Y;
clicked = true;
}
private void TextBlock_PointerReleased(object sender, PointerRoutedEventArgs e)
{
clicked = false;
}
private void TextBlock_PointerMoved(object sender, PointerRoutedEventArgs e)
{
if(clicked == true)
{
yend = e.GetCurrentPoint(this).Position.Y;
double difference;
int textgetal = Convert.ToInt32(Block.Text);
difference = ystart - yend;
textgetal = textgetal + (Convert.ToInt32(difference) / 10);
Block.Text = Convert.ToString(textgetal);
}
}
and like i said this works, but only inside the range of the textblock and not the whole screen like i want it.

WP7, C#, Increase slider value by holding a button

I have to increase the slider control value while holding a button.
As long as I am holding the button the slider has to keep increasing.
For example, the scenario is typical with volume control.
I have a slider for volume and a button Increase for volume.
Now as long as I keep holding the Increase button, the volume (marker) in the slider should keep increasing continuously till I release the button.
What I have achieved is changing the value of the slider on individual click events on the button.
Kindly give your suggestions on how I can achieve this.
According to the book there should be RepeatButton. In this case it will perfectly suit your needs. Try to avoid Thread sleeps. Freezes are not pretty good thing. It's one of first candidates for refactoring.
public bool Ok = false;
public void Do()
{
while (Ok)
{
this.Text += ".";
System.Threading.Thread.Sleep(100);
Application.DoEvents();
//I added dots to the form text , You do your own mission
}
}
private void btnLouder_MouseDown(object sender, MouseEventArgs e)
{
Ok = true;
Do();
}
private void btnLouder_MouseUp(object sender, MouseEventArgs e)
{
Ok = false;
}
Add a TrackBar control to the form and then
Replace the code in While block with this one, it does exactly what you want :
if(trackBar1.Value < trackBar1.Maximum)
trackBar1.Value += 1;

Categories