Richtextbox multiple back colors - c#

I saw this cool thing about having a RichTextBox like a "progress bar" if we can call it like that from another window application and I was trying to do the same.
I was looking at the methods and I couldn't apply any of them on what I'm looking for, I tried to see if there was a similar question but I didn't get so lucky.
How can I accomplish the same result?
Looks like a Richtextbox to me
Based on what Jimi told me I will to explain what I need. The string inside label rappresents a timer which has to change the color in red when it reaches the end, before of that, like at 10 minutes I want it to be Yellow, using that like an alert.
The way the method is wroten doesn't let me to choose which color I want. After that, when the timer is stopped by a button, I want the label to redraws itself and makes it blank without having any kind of colors, looking like a "textbox".

This is a label used as a ProgressBar.
Just an example (quite raw, what I could do with the time I had), but it shows how you can paint the surface of a Control that provides a Paint() event.
It uses a Timer class to increase a value and generates a progress bar effect by calling the Label.Invalidate() method, which raises the Label's Paint event, executing whatever code you have in the label1_Paint() handler.
If you want to test it, paste this code inside a Form which contains a Button (button1) to start the Timer and a Label (label1) that generates the graphic effect.
Then assign the two events - Click() to the Button and Paint() to the Label.
This is how it looks like:
Timer timer;
private bool TimerStarted = false;
private float ProgressMaxValue = 100;
private float Progress = 0;
private int seconds = 0;
private int cents = 0;
private void button1_Click(object sender, EventArgs e)
{
if (TimerStarted) { TimerStop(); return; }
timer = new Timer();
timer.Interval = 20;
Progress = 0;
seconds = 0;
cents = 0;
timer.Tick += (s, ev) => {
++Progress;
if (Progress > ProgressMaxValue) { TimerStop(); return; }
cents += (timer.Interval / 5);
if (cents > 99) { cents = 0; ++seconds; }
this.label1.Invalidate();
};
TimerStarted = true;
timer.Start();
}
private void TimerStop()
{
timer.Stop();
timer.Dispose();
TimerStarted = false;
}
private void label1_Paint(object sender, PaintEventArgs e)
{
StringFormat format = new StringFormat() {
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
e.Graphics.Clear(this.label1.BackColor);
Rectangle rect = label1.ClientRectangle;
rect.Inflate(-1, -1);
e.Graphics.DrawRectangle(Pens.LimeGreen, rect);
RectangleF ProgressBar = new RectangleF(
new PointF(3, 3),
new SizeF((((float)rect.Width - 3) / ProgressMaxValue) * Progress, rect.Height - 4));
e.Graphics.FillRectangle(Brushes.YellowGreen, ProgressBar);
e.Graphics.DrawString($"0.{seconds.ToString("D2")}.{cents.ToString("D2")}", label1.Font, Brushes.White, rect, format);
}

Related

How to change C# Windows Forms label color for 1 sec and reset the label color? [duplicate]

I have a form that displays queue of messages and number this messages can be changed. Really I want to blink label (queue length) when the number of messages were increased to improve form usability.
Should I implement custom control and use additional thread or timer to change color of label? Has anybody implemented so functionality? What is the best solution (less resources and less performance degradation) to implement so behaviour?
SOLUTION:
Form's component with timer that can restrict number of animations per second and implement fade out effect to external control background color.
The following is blinking using async and await
private async void Blink(){
while (true){
await Task.Delay(500);
label1.BackColor = label1.BackColor == Color.Red ? Color.Green : Color.Red;
}
}
I know this is a really old post, but anyone looking for something a little more versatile than the Boolean solutions posted may get some use out of the following:
using System.Diagnostics;
using System.Threading.Tasks;
private async void SoftBlink(Control ctrl, Color c1, Color c2, short CycleTime_ms, bool BkClr)
{
var sw = new Stopwatch(); sw.Start();
short halfCycle = (short)Math.Round(CycleTime_ms * 0.5);
while (true)
{
await Task.Delay(1);
var n = sw.ElapsedMilliseconds % CycleTime_ms;
var per = (double)Math.Abs(n - halfCycle) / halfCycle;
var red = (short)Math.Round((c2.R - c1.R) * per) + c1.R;
var grn = (short)Math.Round((c2.G - c1.G) * per) + c1.G;
var blw = (short)Math.Round((c2.B - c1.B) * per) + c1.B;
var clr = Color.FromArgb(red, grn, blw);
if (BkClr) ctrl.BackColor = clr; else ctrl.ForeColor = clr;
}
}
Which you can call like such:
SoftBlink(lblWarning, Color.FromArgb(30, 30, 30), Color.Red,2000,false);
SoftBlink(lblSoftBlink, Color.FromArgb(30, 30, 30), Color.Green, 2000,true);
Timer timer = new Timer();
timer.Interval = 500;
timer.Enabled = false;
timer.Start();
if( messagesNum > oldMessagesNum)
timer.Tick += new EventHandler( timer_Tick );
else
timer.Tick -= timer_Tick;
void timer_Tick( object sender, EventArgs e )
{
if(messageLabel.BackColor == Color.Black)
messageLabel.BackColor = Color.Red;
else
messageLabel.BackColor = Color.Black;
}
Here is a pretty simple implementation that would work inside your form. You could also create a custom control with the same code and just throw the Timer.Start() into a method for that control.
Create your own UserControl for this, one that inherits from Label instead of from Control directly. Add a StartBlinking method, in which you start a Timer object whose tick event alters the style of the label (changing the BackgroundColor and ForegroundColor properties each time to create the blink effect).
You could also add a StopBlinking method to turn it off, or you could have your Timer stop itself after 5 seconds, perhaps.
You can create a custom component and events to start blinking --which I think is a good solution. The Blinking you can implement with a timer.
Can you use an animated .gif instead (perhaps as the background of the number)? it would make it look like old school web pages, but it might work.
You can use Timer class here.
Here what I have implemented.
Label color blinking on Button_click Event.
//click event on the button to change the color of the label
public void buttonColor_Click(object sender, EventArgs e)
{
Timer timer = new Timer();
timer.Interval = 500;// Timer with 500 milliseconds
timer.Enabled = false;
timer.Start();
timer.Tick += new EventHandler(timer_Tick);
}
void timer_Tick(object sender, EventArgs e)
{
//label text changes from 'Not Connected' to 'Verifying'
if (labelFirst.BackColor == Color.Red)
{
labelFirst.BackColor = Color.Green;
labelFirst.Text = "Verifying";
}
//label text changes from 'Verifying' to 'Connected'
else if (labelFirst.BackColor == Color.Green)
{
labelFirst.BackColor = Color.Green;
labelFirst.Text = "Connected";
}
//initial Condition (will execute)
else
{
labelFirst.BackColor = Color.Red;
labelFirst.Text = "Not Connected";
}
}
this is how i ended up doing it
public partial class MemberDisplay : Form
{
public string Input;
public int MASS_STOP = 1;
public MemberDisplay(string msg)
{
InitializeComponent();
State_Entry();
Input = msg;
}
public void State_Entry()
{
this.SpecialFocus.Select();
this.lbl_TimerTest.Hide();
}
private async void RunBlinkyTest(string msg)
{
while (msg == "GO" && (MASS_STOP == 0))
{
await Task.Delay(500);
lbl_TimerTest.ForeColor =
lbl_TimerTest.ForeColor == Color.Red ?
Color.Black :
Color.Red;
if (msg == "STOP" && (MASS_STOP == 1)) { return; }
}
}
private void btn_TimeTest_Click(object sender, EventArgs e)
{
if (btn_TimeTest.Text == "GO")
{
this.lbl_TimerTest.Show();
MASS_STOP = 0;
RunBlinkyTest("GO");
btn_TimeTest.Text = "STOP";
return;
}
if (btn_TimeTest.Text == "STOP")
{
MASS_STOP = 1;
RunBlinkyTest("STOP");
this.lbl_TimerTest.ForeColor = Color.Black;
this.lbl_TimerTest.Hide();
btn_TimeTest.Text = "GO";
return;
}
}
}

C#. How to avoid double click when I need single click

I am developing a windows form application. Creating a UI for some service. What is happening is when I created the application there are various buttons on which a single click should work to get and set the value but after the completion of code all those buttons are reacting on double click.
when we apply some break point and test, values get and set in single click only but during run-time it need double click. Can anybody help?
I got the solution by writing a piece of code.
Just activated the button on first click.
bool firstClick = true;
{if(firstClick) { button.select(); //Activating the button } }
Thanks all for your responses.
Here is a full Article from MSDN on how to use single-click only vs double-click only. Also, it states how you can handle events and differentiate between a single click and a double click.
The article uses boolean and timers to do that. You might need to use a Dictionary<Button, boolean> if you have multiple buttons. Hope it helps.
Here is the example if the link got down or removed for some reaosn:
Handle the MouseDown event and determine the location and time span
between clicks using the appropriate SystemInformation properties and
a Timer component. Perform the appropriate action depending on whether
a click or double-click takes place. The following code example
demonstrates how this can be done.
class Form1 : Form
{
private Rectangle hitTestRectangle = new Rectangle();
private Rectangle doubleClickRectangle = new Rectangle();
private TextBox textBox1 = new TextBox();
private Timer doubleClickTimer = new Timer();
private ProgressBar doubleClickBar = new ProgressBar();
private Label label1 = new Label();
private Label label2 = new Label();
private bool isFirstClick = true;
private bool isDoubleClick = false;
private int milliseconds = 0;
[STAThread]
public static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
public Form1()
{
label1.Location = new Point(30, 5);
label1.Size = new Size(100, 15);
label1.Text = "Hit test rectangle:";
label2.Location = new Point(30, 70);
label2.Size = new Size(100, 15);
label2.Text = "Double click timer:";
hitTestRectangle.Location = new Point(30, 20);
hitTestRectangle.Size = new Size(100, 40);
doubleClickTimer.Interval = 100;
doubleClickTimer.Tick +=
new EventHandler(doubleClickTimer_Tick);
doubleClickBar.Location = new Point(30, 85);
doubleClickBar.Minimum = 0;
doubleClickBar.Maximum = SystemInformation.DoubleClickTime;
textBox1.Location = new Point(30, 120);
textBox1.Size = new Size(200, 100);
textBox1.AutoSize = false;
textBox1.Multiline = true;
this.Paint += new PaintEventHandler(Form1_Paint);
this.MouseDown += new MouseEventHandler(Form1_MouseDown);
this.Controls.AddRange(new Control[] { doubleClickBar, textBox1,
label1, label2 });
}
// Detect a valid single click or double click.
void Form1_MouseDown(object sender, MouseEventArgs e)
{
// Verify that the mouse click is in the main hit
// test rectangle.
if (!hitTestRectangle.Contains(e.Location))
{
return;
}
// This is the first mouse click.
if (isFirstClick)
{
isFirstClick = false;
// Determine the location and size of the double click
// rectangle area to draw around the cursor point.
doubleClickRectangle = new Rectangle(
e.X - (SystemInformation.DoubleClickSize.Width / 2),
e.Y - (SystemInformation.DoubleClickSize.Height / 2),
SystemInformation.DoubleClickSize.Width,
SystemInformation.DoubleClickSize.Height);
Invalidate();
// Start the double click timer.
doubleClickTimer.Start();
}
// This is the second mouse click.
else
{
// Verify that the mouse click is within the double click
// rectangle and is within the system-defined double
// click period.
if (doubleClickRectangle.Contains(e.Location) &&
milliseconds < SystemInformation.DoubleClickTime)
{
isDoubleClick = true;
}
}
}
void doubleClickTimer_Tick(object sender, EventArgs e)
{
milliseconds += 100;
doubleClickBar.Increment(100);
// The timer has reached the double click time limit.
if (milliseconds >= SystemInformation.DoubleClickTime)
{
doubleClickTimer.Stop();
if (isDoubleClick)
{
textBox1.AppendText("Perform double click action");
textBox1.AppendText(Environment.NewLine);
}
else
{
textBox1.AppendText("Perform single click action");
textBox1.AppendText(Environment.NewLine);
}
// Allow the MouseDown event handler to process clicks again.
isFirstClick = true;
isDoubleClick = false;
milliseconds = 0;
doubleClickBar.Value = 0;
}
}
// Paint the hit test and double click rectangles.
void Form1_Paint(object sender, PaintEventArgs e)
{
// Draw the border of the main hit test rectangle.
e.Graphics.DrawRectangle(Pens.Black, hitTestRectangle);
// Fill in the double click rectangle.
e.Graphics.FillRectangle(Brushes.Blue, doubleClickRectangle);
}
}
You can simply identify single click and double using a timer. Here is the example
class Form1 : Form
{
Timer timer;
public Form1()
{
InitializeComponent();
timer = new Timer();
timer.Interval = 500;
timer.Tick += new EventHandler(Timer_Tick);
}
private void App_MouseDown(object sender, MouseEventArgs e)
{
if (e.Clicks == 1)
{
timer.Start();
}
else
{
timer.Stop();
doubleClick();
}
}
private void Timer_Tick(object sender, EventArgs e)
{
timer.Stop();
singleClick();
}
//Single click
public void singleClick()
{
MessageBox.Show("Single Click.");
}
//Double click
public void doubleClick()
{
MessageBox.Show("Double Click.");
}
}

How to fade in and fade out (Fading transition ) image on panel(backgroud image)?

I'm sending to my method different images and I want insert some effect to this change.
How can I fade in and fade out images?
private void ShowImage(Image image, ImageLayout imageLayout, int numberOfSeconds)
{
try
{
if (this.image_timer != null)
this.KillImageTimer();
this.customer_form.DisplayImage(image, imageLayout);
this.image_timer = new Timer();
this.image_timer.Tick += (object s, EventArgs a) => NextImage();
this.image_timer.Interval = numberOfSeconds* 1000;
this.image_timer.Start();
}
catch
{
//Do nothing
}
public void DisplayImage(Image image, ImageLayout imageLayout)
{
panel1.BackgroundImage = image;
panel1.BackgroundImageLayout = imageLayout;
}
There are no built-in fading transitions in Winforms.
So you will need to write one yourself.
The simplest one I can think of uses a second Panel, that is layered upon the first one and in fact needs to be inside the first Panel or else the transparency effect won't work..
Here is the setup, using two Panels:
public Form1()
{
InitializeComponent();
pan_image.BackgroundImage = someImage;
pan_layer.Parent = pan_image;
pan_layer.BackColor = pan_image.BackColor;
pan_layer.Size = pan_image.Size;
pan_layer.Location = Point.Empty;
}
For the fading animation I use a Timer. This is a quick code example:
Timer timer1 = new Timer();
int counter = 0;
int dir = 1; // direction 1 = fade-in..
int secondsToWait = 5;
int speed1 = 25; // tick speed ms
int speed2 = 4; // alpha (0-255) change speed
void timer1_Tick(object sender, EventArgs e)
{
// we have just waited and now we fade-out:
if (dir == 0)
{
timer1.Stop();
dir = -speed2;
counter = 254;
timer1.Interval = speed2;
timer1.Start();
}
// the next alpha value:
int alpha = Math.Min(Math.Max(0, counter+= dir), 255);
button1.Text = dir > 0 ? "Fade In" : "Fade Out";
// fully faded-in: set up the long wait:
if (counter >= 255)
{
timer1.Stop();
button1.Text = "Wait";
timer1.Interval = secondsToWait * 1000;
dir = 0;
timer1.Start();
}
// fully faded-out: try to load a new image and set direction to fade-in or stop
else if (counter <= 0)
{
if ( !changeImage() )
{
timer1.Stop();
button1.Text = "Done";
}
dir = speed2;
}
// create the new, semi-transparent color:
Color col = Color.FromArgb(255 - alpha, pan_image.BackColor);
// display the layer:
pan_layer.BackColor = col;
pan_layer.Refresh();
}
I start it in a Button, on which I also show the current state:
private void button1_Click(object sender, EventArgs e)
{
dir = speed2;
timer1.Tick += timer1_Tick;
timer1.Interval = speed1;
timer1.Start();
}
As you can see I use two speeds you can set: One to control the speed of the Timer and one to control the steps by which the transparency changes on each Tick.
The effect is created by simply changing the Color from the BackgroundColor of the image Panel to fully transparent and back, waiting in between for a specified number of seconds.
And the end of the effect I call a function changeImage() to change the images. If this function returns false the Timer is stopped for good..
I'm pretty sure this could be written in a cleaner and more elegant way, but as it is it seems to work..
Update
for flicker-free display use a double-buffered control, like this Panel subclass:
class DrawPanel : Panel
{
public DrawPanel() { DoubleBuffered = true; }
}
Here is a sample implementation for changeImage:
bool changeImage()
{
if (pan_image.BackgroundImage != null)
{
var img = pan_image.BackgroundImage;
pan_image.BackgroundImage = null;
img.Dispose();
}
pan_image.BackgroundImage = Image.FromFile(imageFiles[index++]);
return index < imageFiles.Count;
}
It assumes two class level variables: a List<string> imageFiles filled with file names of images for a slide-show and an int index = 0.

How to implement a blinking label on a form

I have a form that displays queue of messages and number this messages can be changed. Really I want to blink label (queue length) when the number of messages were increased to improve form usability.
Should I implement custom control and use additional thread or timer to change color of label? Has anybody implemented so functionality? What is the best solution (less resources and less performance degradation) to implement so behaviour?
SOLUTION:
Form's component with timer that can restrict number of animations per second and implement fade out effect to external control background color.
The following is blinking using async and await
private async void Blink(){
while (true){
await Task.Delay(500);
label1.BackColor = label1.BackColor == Color.Red ? Color.Green : Color.Red;
}
}
I know this is a really old post, but anyone looking for something a little more versatile than the Boolean solutions posted may get some use out of the following:
using System.Diagnostics;
using System.Threading.Tasks;
private async void SoftBlink(Control ctrl, Color c1, Color c2, short CycleTime_ms, bool BkClr)
{
var sw = new Stopwatch(); sw.Start();
short halfCycle = (short)Math.Round(CycleTime_ms * 0.5);
while (true)
{
await Task.Delay(1);
var n = sw.ElapsedMilliseconds % CycleTime_ms;
var per = (double)Math.Abs(n - halfCycle) / halfCycle;
var red = (short)Math.Round((c2.R - c1.R) * per) + c1.R;
var grn = (short)Math.Round((c2.G - c1.G) * per) + c1.G;
var blw = (short)Math.Round((c2.B - c1.B) * per) + c1.B;
var clr = Color.FromArgb(red, grn, blw);
if (BkClr) ctrl.BackColor = clr; else ctrl.ForeColor = clr;
}
}
Which you can call like such:
SoftBlink(lblWarning, Color.FromArgb(30, 30, 30), Color.Red,2000,false);
SoftBlink(lblSoftBlink, Color.FromArgb(30, 30, 30), Color.Green, 2000,true);
Timer timer = new Timer();
timer.Interval = 500;
timer.Enabled = false;
timer.Start();
if( messagesNum > oldMessagesNum)
timer.Tick += new EventHandler( timer_Tick );
else
timer.Tick -= timer_Tick;
void timer_Tick( object sender, EventArgs e )
{
if(messageLabel.BackColor == Color.Black)
messageLabel.BackColor = Color.Red;
else
messageLabel.BackColor = Color.Black;
}
Here is a pretty simple implementation that would work inside your form. You could also create a custom control with the same code and just throw the Timer.Start() into a method for that control.
Create your own UserControl for this, one that inherits from Label instead of from Control directly. Add a StartBlinking method, in which you start a Timer object whose tick event alters the style of the label (changing the BackgroundColor and ForegroundColor properties each time to create the blink effect).
You could also add a StopBlinking method to turn it off, or you could have your Timer stop itself after 5 seconds, perhaps.
You can create a custom component and events to start blinking --which I think is a good solution. The Blinking you can implement with a timer.
Can you use an animated .gif instead (perhaps as the background of the number)? it would make it look like old school web pages, but it might work.
You can use Timer class here.
Here what I have implemented.
Label color blinking on Button_click Event.
//click event on the button to change the color of the label
public void buttonColor_Click(object sender, EventArgs e)
{
Timer timer = new Timer();
timer.Interval = 500;// Timer with 500 milliseconds
timer.Enabled = false;
timer.Start();
timer.Tick += new EventHandler(timer_Tick);
}
void timer_Tick(object sender, EventArgs e)
{
//label text changes from 'Not Connected' to 'Verifying'
if (labelFirst.BackColor == Color.Red)
{
labelFirst.BackColor = Color.Green;
labelFirst.Text = "Verifying";
}
//label text changes from 'Verifying' to 'Connected'
else if (labelFirst.BackColor == Color.Green)
{
labelFirst.BackColor = Color.Green;
labelFirst.Text = "Connected";
}
//initial Condition (will execute)
else
{
labelFirst.BackColor = Color.Red;
labelFirst.Text = "Not Connected";
}
}
this is how i ended up doing it
public partial class MemberDisplay : Form
{
public string Input;
public int MASS_STOP = 1;
public MemberDisplay(string msg)
{
InitializeComponent();
State_Entry();
Input = msg;
}
public void State_Entry()
{
this.SpecialFocus.Select();
this.lbl_TimerTest.Hide();
}
private async void RunBlinkyTest(string msg)
{
while (msg == "GO" && (MASS_STOP == 0))
{
await Task.Delay(500);
lbl_TimerTest.ForeColor =
lbl_TimerTest.ForeColor == Color.Red ?
Color.Black :
Color.Red;
if (msg == "STOP" && (MASS_STOP == 1)) { return; }
}
}
private void btn_TimeTest_Click(object sender, EventArgs e)
{
if (btn_TimeTest.Text == "GO")
{
this.lbl_TimerTest.Show();
MASS_STOP = 0;
RunBlinkyTest("GO");
btn_TimeTest.Text = "STOP";
return;
}
if (btn_TimeTest.Text == "STOP")
{
MASS_STOP = 1;
RunBlinkyTest("STOP");
this.lbl_TimerTest.ForeColor = Color.Black;
this.lbl_TimerTest.Hide();
btn_TimeTest.Text = "GO";
return;
}
}
}

Effect To Show Panel in C#.net

I Want Use a Panel in a Windows Form in C#.net. I Set Visible Property of this Control to false And When I Click on a Button, Panel is showed. I Want Show a Panel by some Effect.
Please Help me for this
You are leaving us guessing about what kind of effect you are looking for. I'll just arbitrarily pick a collapse and expand effect. It takes a Timer, you implement the effect in a Tick event handler. Here's an example, it requires a Panel, Timer and Button:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
timer1.Interval = 16;
timer1.Tick += new EventHandler(timer1_Tick);
panel1.BackColor = Color.Aqua;
mWidth = panel1.Width;
}
int mDir = 0;
int mWidth;
void timer1_Tick(object sender, EventArgs e) {
int width = panel1.Width + mDir;
if (width >= mWidth) {
width = mWidth;
timer1.Enabled = false;
}
else if (width < Math.Abs(mDir)) {
width = 0;
timer1.Enabled = false;
panel1.Visible = false;
}
panel1.Width = width;
}
private void button1_Click(object sender, EventArgs e) {
mDir = panel1.Visible ? -5 : 5;
panel1.Visible = true;
timer1.Enabled = true;
}
}
The only effect I can think of is to expand the panel by using a timer and change the size of the panel step-by-step.
I would recommend you to use WPF instead of Winforms that is very good at doing this kind of stuff. You can animate all properties of the control like location, size, alpha. Please, check these articles on WPF animation
WPF Animation overview
Walkthroughs: Create a Custom Animated Button

Categories

Resources