Blinking text in progressbar? - c#

i have made a cool progressbar with text in the middle of it. Here is my code:
private void timer2_Tick(object sender, EventArgs e)
{
progressBar1.Increment(+1);
int percent = progressBar1.Value;
progressBar1
.CreateGraphics()
.DrawString(
percent.ToString() + "%",
new Font("Arial", (float)8.25, FontStyle.Regular),
Brushes.Black,
new PointF(progressBar1.Width / 2 - 10,
progressBar1.Height / 2 - 7)
);
if (progressBar1.Value >= 99)
{
timer2.Stop();
this.Close();
}
}
For some reason, the text shows up then disappears and other weird stuff. Why is that, and how do i fix it?

Try moving the drawing code into the Paint event, you are basically modifying the control's visuals, so you need to handle this instead of the default painting behaviour.

Your drawing gets erased whenever the control is repainted.
Instead, you need to set a flag indicating whether to draw the text right now, then handle the Paint event, and, if the flag is true, draw the text.
In the timer tick handler, toggle the flag and call Invalidate().

Another approach would be to create a UserControll and use a label on top of the progress bar, and use each separately, this might prove easier to do, hardly any additional code will be needed for this.

Related

C# WinForms TabStrip control: no accelerator

I am using a tab strip control on a WinForms form. I make use of keyboard accelerators as much as possible. When I set the Text property of a TabPage to e.g. &Documents, the text on the tab is literally &Documents instead of the letter D being underlined.
The help about TabStrip and TabPage doesn't cover this topic. The property ShowKeyboardCues is read-only. Google is helpless.
Can anyone give me a hint how to show accelerators?
How can I set up keyboard shortcuts for a Windows Forms TabControl? gives tips on setting up keyboard shortcuts for it.. In terms of showing an accelerator though, you'll have to draw them yourself
Set the tabControl's DrawMode to OwnerDrawFixed then do some code to draw the tabs, for example (I had to try hard to make it this ugly)
private void tabControl1_DrawItem(object sender, DrawItemEventArgs e)
{
//Change appearance of tabcontrol
Brush backBrush = Brushes.Red;
Brush foreBrush = Brushes.Blue;
e.Graphics.FillRectangle(backBrush, e.Bounds);
Rectangle r = e.Bounds;
r = new Rectangle(r.X, r.Y + 3, r.Width, r.Height - 3);
e.Graphics.DrawString("my label", e.Font, foreBrush, r);
var sz = e.Graphics.MeasureString("my ", e.Font);
e.Graphics.DrawString("_", Font, foreBrush, r.X + sz.Width - 2, r.Y + 2);
}
Joking aside, setting up some ugly colors does help you see where the bounds of the drawing area are etc. I'm sure you'll tart it up..
Neither of these controls supports that functionality. It is possible to simulate it, but it is a long and complicated task that I would not recommend because it is non-standard functionality. As a result it is unlikely that anyone would expect it to occur. On the other hand, changing tabs using Ctrl+Tab is standard behaviour so is already automatically supported.
If you did want to do this, you would need to:
Subclass the Control
Override the painting and draw the text on the tab yourself
Get a preview of the keydown event and use that to determine if the key combination you wanted was pressed
Select the correct tab programmatically based on the keypress that you have intercepted
As I say, I would not recommend this because it is not normal behaviour for that control and because the complexity means that it is likely to be buggy. But it is possible...

User control repainting only when window moved

I have a custom user control which displays waveform of an audio file. I've put two instances of controls on a form. The second instance works as expected while the first instance causes the problem mentioned.
What I am doing is drawing a vertical (red) line, indicating current position. The problem is best seen in a youtube video.
This is the code of my custom controller (OnPaint() - notice that I invalidate only the region affected by the red vertical line):
protected override void OnPaint(PaintEventArgs e)
{
[...]
Invalidate(new Rectangle(x_pos-5, 0, x_pos, this.Height));
using (Pen linePen = new Pen(Color.Red, 1.5f))
{
e.Graphics.DrawLine(linePen, x_pos, 0, x_pos, this.Height);
Invalidate(new Rectangle(x_pos-2,0,x_pos+2,this.Height));
}
base.OnPaint(e);
}
Q: Since the OnPaint method is equivalent for both controls why do I need to move the window to repaint the first control (waveform)?
The problem with OnPaint is that it's only called when it's necessary, for example when the window is moved, resized, after it's brought back from minimized state, or when another window is moved on top of it.
In order to periodically repaint the window (or parts of it), you'll need to add a Timer to the form and implement its Tick event.
private void timer1_Tick(object sender, EventArgs e)
{
this.Invalidate();
}
By default, Timer.Interval is set to 100 (100 ms). If you only want to update your rectangle every second, you can increase that value to 1000 if you want.

c# how to create a teleprompter like application in winforms?

I'm developing a C# WinForms application. I can't find a solution to this probably because I'm new.
I need to create a teleprompter like text that scrolls from the bottom and goes up in a loop.
is there any simple solution or a code snippet?
An example would be nice so that I can understand how it is being done.
You could also create a Label control with text, and simply decrease its Vertical position with 1 (in pixels) every 1/20th of a second or so.
The idea is you could use the timer control, handle it Tick event
myTimer.Tick += new EventHandler(TimerEventProcessor);
Set myTimer.Interval = 1000;// event will fire every sec
private static void TimerEventProcessor(Object myObject,EventArgs myEventArgs) {
/// your logic to add new text, and change text position to give scroll effect
}
In TimerEventProcessor, put you logic to change text position that is to change it y coordinate, add new text in the bottom, this way you can create the scroll effect
In the timer.tick event handler you could do
if(label.Location.Y < 20)
label.Location = new Point(label.Location.X, this.ClientSize.Height);
else
label.Location = new Point(label.Location.X, label.Location.Y - 1);
Hope this help

Output to a Picture Box Alternative

For a project I'm working on, a stopwatch-like timer needs to be displayed to the form. If I remember correctly in VB, text could be outputted to a picture box, but I can't find a way to do it in c#. A label would work, if there is a way to prevent the resizing of the box. Thanks.
A Label would probably be the simplest option. I'm not sure why you would need to prevent resizing of the picturebox (which is also simple to do).
If you are worried about your picturebox being resized and your Label no longer being centered, or being the wrong size, you can just put code in the resize event which dynamically updates the size and location of the Label and its font, based on the current size of the picturebox.
However, if you are determined to not use labels, you can always have your picturebox subscribe to the Paint event and then use e.Graphics to just draw your text whenever the picturebox is repainted.
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (Font myFont = new Font("Microsoft Sans Serif", 10))
{
e.Graphics.DrawString("This time is...Hammertime", myFont, Brushes.Black, new Point(0,0));
}
}
However, you would also have to redraw this for every iteration of your timer.
Like I said, Label would be a better option than this. Calling e.Graphics wouldn't give you any real advantage over Label , but it would create more things for you to worry about.
Using a TextBox is probably the most appropriate thing for this; just set ReadOnly to true.

Problem with using Paint event in c#

I have used this below code before and was working perfectly. When I use the same
in one of my window form, the color of the form is not changing.
I mean after the page loads it shows the default color of the form. But when I try to debug the code below, it changes the color of the form perfectly. The problem is, after executing the last line of the code the color of the form goes back to the default color.
Am I missing something?
The form looks like a windows taskbar, and it has one tab control in it.
private void TaskBar_Paint(object sender, PaintEventArgs e)
{
Graphics mGraphics = e.Graphics;
Pen pen1 = new Pen(Color.FromArgb(96, 155, 173), 1);
Rectangle Area1 = new Rectangle(0, 0, this.Width - 2, this.Height - 2);
LinearGradientBrush LGB = new LinearGradientBrush(Area1,
Color.FromArgb(96, 155, 173),
Color.FromArgb(245, 251, 251),
LinearGradientMode.Vertical);
mGraphics.FillRectangle(LGB, Area1);
mGraphics.DrawRectangle(pen1, Area1);
}
There isn't much to go on here. What is this handler attached to? The Paint event of the Form? If so, you should override OnPaint() instead of attaching to the handler. My guess is that some other method is doing some painting too. You need to track that down. Without more code, it is not very likely that anyone here can help you. Sorry.

Categories