Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to override the paint event of a Windows Form, however all painting I do to the Form stays, even after I've Invalidate() and Update() the Form.
I am using a Timer to Invalidate() and Update() the Form, which causes the OnPaint() to be called
Here is the code:
// In the constructor the timer is created and enabled
private void UpdaterElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
WIDGET.Invalidate();
WIDGET.Update();
}
private void WIDGET_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
String text = DateTime.Now.ToString("hh:mm:ss tt");
e.Graphics.DrawString(text, new Font("Arial", 32), Brushes.Black, new Point(0, 0));
}
It's not supposed to clear the form (though getting paint events triggered by covering your window should do the job anyway). Simply clear it yourself if you need to:
e.Graphics.Clear(/* insert your color here */);
You have to clear graphics with some color which should be considered as transparent and then simply setup transparency key.
e.Graphics.Clear(Color.Purple);
this.TransparencyKey = Color.Purple;
Related
Okay so I have created a Flowlayoutpanel in which about 70 usercontrols, all squares of 50x50 pixels with an animated grass gif inside a picturebox inside of it. I want to make these hide-able but not be removed so there's a white space left. I've been able to do that quite consistently by just using Hide() and changing the background colour to be transparant so I don't have to hide the entire UserControl.
Problem comes up here, I want these gifs to reappear on a timer, so I've created a timer that references a method which just uses a show() again to show said gif and yet it refuses to do so if I create a seperate button to do so or not.
I have searched quite a bit but I think this is a problem only because I'm consistently missing something in my code so no other question really seems to answer my troubles. Because it's such a simple question I feel kind of embarrassed even asking it but oh well.
This is the timer event that calls the method in the other class
private void GrasTerugkeerTimer_Tick(object sender, EventArgs e)
{
var instance = new GrasVeldUC();
instance.TerugKeerGras();
}
This is the events and methods I've set up to show and hide the picturebox that the gif is inside of
public partial class GrasVeldUC : UserControl
{
public GrasVeldUC()
{
InitializeComponent();
this.BackColor = Color.White;
}
private void GrasVeldUC_Click(object sender, EventArgs e)
{
this.BackColor = Color.FromArgb(0, 255, 255, 255);
PIBGrasUC.Hide();
}
private void PIBGrasUC_Click(object sender, EventArgs e)
{
this.BackColor = Color.FromArgb(0, 255, 255, 255);
PIBGrasUC.Hide();
}
public void TerugKeerGras()
{
this.BackColor = Color.FromArgb(100, 255, 255, 255);
PIBGrasUC.Show();
}
}
Now I expected this to just work and just show the picturebox again and yet whatever I tried, creating a seperate method that references the method in the other class, it would not work. And the method in the class "GrasVeldUC" does work I put a messagebox inside of it to test and it worked perfectly.
You can just toggle the picturebox.visible as needed.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I want that if i click on an image it gives a visual effect like whirl effect or glow effect or anything else on specific part around the point where i clicked with the mouse. for example if anyone has used the picture password of UC browser of windows phone exactly the same i want.
I have not tried anything because i have no knowledge of animation and graphics hence i haven't tried anything.
public void start()
{
messagebox.show("i haven't tried anything yet no knowledge of animation");
}
This code is nothing but i wrote it because i was not able to post the question.
In Winforms you could write code like this:
int AnimationCounter = 0;
Point AnimationCenter = Point.Empty;
Timer AnimationTimer = new Timer();
private void pictureBox1 _MouseClick(object sender, MouseEventArgs e)
{
AnimationCenter = e.Location;
AnimationTimer.Interval = 20;
AnimationTimer.Start();
}
void AnimationTimer_Tick(object sender, EventArgs e)
{
if (AnimationCounter > 15)
{
AnimationTimer.Stop();
AnimationCounter = 0;
pictureBox1.Invalidate();
}
else
{
AnimationCounter += 1;
pictureBox1.Invalidate();
}
}
private void pictureBox1 _Paint(object sender, PaintEventArgs e)
{
if (AnimationCounter > 0)
{
int ac = AnimationCounter / 2;
e.Graphics.DrawEllipse(Pens.Orange, AnimationCenter.X - ac,
AnimationCenter.Y - ac, ac * 2, ac * 2);
}
}
Don't forget to hook up the Paint and MouseClick event and also the AnimationTimer_Tick event.!
The result will draw a growing circle at the spot you click on which will disappear after ca. 10 * 20 ms..
Update: The first version suffered from repeatedly hooking up the Tick event. This one is better tested ;-)
Question:
How do you properly draw on a winform from a method other than the OnPaint() method?
Additional Information:
The code I have now draws some background lines for a TicTacToe game in the OnPaint() method. Then I use the Mouse_Click event and am running this code which apparently is not proper:
private void TicTacToe_MouseClick(object sender, MouseEventArgs e)
Graphics g = this.CreateGraphics();
g.DrawEllipse(this.penRed, this.Rectangle);
For reasons I do not understand, it does draw the circle, but when minimizing or moving the form off screen it erases the circles but not the lines from the OnPaint() method.
You are doing a lot of "view" but no "model".
When you want to create a shape, when the mouse button goes down/up, create some DATA representing the shape.
Your data structures represent the persistent information (it is the data that allows you to save and load this information between sessions).
All your paint function needs to do is look at the DATA structures and paint it. This will therefore persist between sizing/hiding/showing.
The problem is that Windows windows (that includes WinForms) have no graphical memory of their own unless their creator provides such memory and it is only a matter of time before that particular window wilk get overwritten or hidden and eventually need to be repainted. You're painting to the screen ( you might say ) and others can do the same. The only convention you can rely on is that the OnPaint will get called when needed. Basically it's alright to use your philosophy and draw whenever you need to (not on some misterious and unpredictable schedule). For that check out my solution.
You should use a "backbuffer bitmap" like:
private Bitmap bb;
protected override void OnResize(EventArgs e) {
this.bb = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
this.InitBackBuffer();
}
private void InitBackBuffer() {
using (var g = Graphics.FromImage(this.bb)) {
// do any of the "non dissapearing line" drawing here
}
}
private void TicTacToe_MouseClick(object sender, MouseEventArgs e)
using (Graphics g = Graphics.FromImage(this.bb))
g.DrawEllipse(this.penRed, this.Rectangle);
this.Invalidate();
}
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
e.Graphics.DrawImageUnscaled(this.bb);
}
Try that. That should do it :)
What you are doing is drawing on the form "asynchronously" (from the OnPaint method). You see, the OnPaint method is what Windows Forms relies on to draw your entire form. When something happens to your From, it is invalidated and OnPaint is called again. If something isn't drawn in that method, then it will not be there after that happens.
If you want a button to trigger something to appear permanently then what you need to do is Add that object to a collection somewhere, or set a variable related to it. Then call Refresh() which calls Invalidate() and Update() Then, during OnPaint, draw that object (ellipis).
If you want it to still be there after something happens to your form, such as minimize, you have to draw it during OnPaint.
Here's my suggestion:
public partial class Form1 : Form
{
Rectangle r = Rectangle.Empty;
Pen redPen = new Pen(Color.Red);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
r = new Rectangle(50, 50, 100, 100);
Refresh();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (r != Rectangle.Empty)
{
e.Graphics.DrawRectangle(redPen, r);
}
}
}
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I have a pictureBox in a Form. In the middle of that pictureBox, I've placed the name of a chosen photo.
Now, I want to color the background of that chosen name.
How can I do that?
I'm not sure what you mean, but a PictureBox's content is an image. If you want to simply display text, use a Label. If you want it to have a specific background color, set its BackColor property to the color that you want.
Example:
private void Form1_Load(object sender, EventArgs e)
{
var label = new Label {BackColor = Color.White};
Controls.Add(label);
}
EDIT:
I allowed myself to re-use part of Sampath's example above to adapt it to the user's comment.
void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (var font = new Font("Arial", 14))
{
const string pictureName = "Picture.jpg";
var textPosition = new Point(10, 10);
//Drawing logic begins here.
var size = e.Graphics.MeasureString(pictureName, font);
var rect = new RectangleF(textPosition.X, textPosition.Y, size.Width, size.Height);
//Filling a rectangle before drawing the string.
e.Graphics.FillRectangle(Brushes.Red, rect);
e.Graphics.DrawString(pictureName, font, Brushes.Green, textPosition);
}
}
You can try below sample.
Just add a picture box to your form, and add an event handler for the Paint event:
You want to use the Paint event in the PictureBox. You get the graphics reference from e.Graphics, and then use the DrawString() that you have in your sample.
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (Font myFont = new Font("Arial", 14))
{
e.Graphics.DrawString("Hello .NET Guide!", myFont, Brushes.Green, new Point(2, 2));
}
}
Hope this will help to you.
Your problem might be as simple as changing the background color property for the control, which you change in the properties window.
Relatively new to C#; hopefully I'm just overlooking something simple.
I have a form named 'Exercise1' which contains a picture box called 'drawingArea' and a few buttons. The code for the constructor of Exercise1 is as follows:
public Exercise1()
{
InitializeComponent();
paper = drawingArea.CreateGraphics();
balloon = new Balloon("redBalloon", Color.Red, drawingArea.Width / 2,
drawingArea.Height / 2, 30);
paper.Clear(Color.White);
balloon.Display(paper);
}
...
'paper' and 'balloon' are created as globals above the constructor for use in the other methods on the form. Both 'paper' and 'balloon' work as initialized in the constructor in the other methods defined on the form.
For whatever reason, the commands
paper.Clear(Color.White);
and
balloon.Display(paper);
Which should clear the picture box and show a red ellipse, don't execute (at least visibly). What gives?
UPDATE:
Think I'm going to like this website... You guys are quick!
#Nitesh: The constructor for Exercise1 is called from another form. Code is as follows:
private void button1_Click(object sender, EventArgs e)
{
int exSelector = (int)numericUpDown1.Value;
switch (exSelector)
{
case 1:
Exercise1 form1 = new Exercise1();
form1.Show();
break;
...
#Sean Dunford: Yes and yes it is.
#RBarryYoung: Was playing around with that a bit, but had no luck. What command triggers a Form_Load event for Exercise1?
UPDATE: This altered code works as expected:
public Exercise1()
{
InitializeComponent();
paper = drawingArea.CreateGraphics();
drawingArea.BackColor = Color.White;
drawingArea.Paint += new PaintEventHandler(this.drawingArea_Paint);
balloon = new Balloon("redBalloon", Color.Red, drawingArea.Width / 2, drawingArea.Height / 2, 30);
}
private void drawingArea_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(Color.White);
balloon.Display(e.Graphics);
}
...
Thanks for all the help!
You cannot do drawing in the constructor. To do proper drawing, you need to have the form shown on the screen. You can try using the Shown event to do your rendering (this may get lost when the form is redrawn, though).
Usually the best way is to set whatever flags you need in the constructor and then use the Paint event of the form to do all painting. Later on, when you need to repaint something, set up whatever state needs to be rendered, invalidate your form (this results in a Paint event) and then you can repaint the new state.
If you try to do customized drawing (outside your Paint event) you'll run the risk of things randomly going blank or your drawing may disapper when you resize/minimize your form.
You use Graphics in a constructor, that means that you draw on the paper only once, any redraw for whatever reason that happens after constructor will draw the drawingArea in its original way. Try to add PaintEventHandler to drawingArea and then call inside balloon.Display(e.Graphics);
public Exercise1()
{
InitializeComponent();
balloon = new Balloon("redBalloon", Color.Red, drawingArea.Width / 2,
drawingArea.Height / 2, 30);
drawingArea.Paint += new PaintEventHandler(drawingArea_Paint);
}
void drawingArea_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(Color.White);
baloon.Display(e.Graphics);
}
You should be overriding the forms OnPaint event handler. In doing so, you are able to get the graphics context which will redraw your paper and balloon areas.