Drawing Text on Panel
-
Hi everyone. I'm trying to draw text of string on a panel control outside the Paint event but surprisingly, nothing is being drawn. I actually cannot figure out what is wrong with my code. I decided to create a small application to test that and again nothing is being drawn. The small code I wrote to test it is shown below:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();DrawText(); } private void DrawText() { Graphics grfx = panel.CreateGraphics(); grfx.DrawString("Problem drawing text on Panel", panel.Font, Brushes.Black, 50, 50); grfx.Dispose(); } }
}
The variable 'panel' is an object of Panel which has been placed on the form with a Dock property 'Fill'. After compiling the text is not drawn. I don't know what I am doing wrong. Please help.
-
Hi everyone. I'm trying to draw text of string on a panel control outside the Paint event but surprisingly, nothing is being drawn. I actually cannot figure out what is wrong with my code. I decided to create a small application to test that and again nothing is being drawn. The small code I wrote to test it is shown below:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();DrawText(); } private void DrawText() { Graphics grfx = panel.CreateGraphics(); grfx.DrawString("Problem drawing text on Panel", panel.Font, Brushes.Black, 50, 50); grfx.Dispose(); } }
}
The variable 'panel' is an object of Panel which has been placed on the form with a Dock property 'Fill'. After compiling the text is not drawn. I don't know what I am doing wrong. Please help.
The most obvious thing here is that your form hasn't actually finished loading yet, and you are attempting to draw the text once and once only (before the form is actually rendered). What you need to do is draw the string in the Paint event handler. As you are drawing this in a panel, you would hook into the paint event handler on the panel like this:
private void panel_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawString("Problem drawing text on panel", panel.Font, Brushes.Black, 50, 50);
}*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
My blog | My articles | MoXAML PowerToys | Mole 2010 - debugging made easier - my favourite utility
-
Hi everyone. I'm trying to draw text of string on a panel control outside the Paint event but surprisingly, nothing is being drawn. I actually cannot figure out what is wrong with my code. I decided to create a small application to test that and again nothing is being drawn. The small code I wrote to test it is shown below:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();DrawText(); } private void DrawText() { Graphics grfx = panel.CreateGraphics(); grfx.DrawString("Problem drawing text on Panel", panel.Font, Brushes.Black, 50, 50); grfx.Dispose(); } }
}
The variable 'panel' is an object of Panel which has been placed on the form with a Dock property 'Fill'. After compiling the text is not drawn. I don't know what I am doing wrong. Please help.
In actual fact the text is getting drawn, but every time the panel is repainted it is going to clear it out (and this will happen as soon as the form is loaded). You say you want to do this outside the Paint event, but this is where this sort of thing should be handled. You should just call the panel's Invalidate method every time the text is updated. Something like this:-
string text;
public Form1() { InitializeComponent(); text = "No problem drawing in paint method!"; panel.Invalidate(); } private void panel\_Paint(object sender, PaintEventArgs e) { Graphics grfx = e.Graphics; grfx.DrawString(text, panel.Font, Brushes.Black, 50, 50); grfx.Dispose(); } private void button1\_Click(object sender, EventArgs e) { text = "Changed with the click of a button !"; panel.Invalidate(); }
Hope this helps
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
-
Hi everyone. I'm trying to draw text of string on a panel control outside the Paint event but surprisingly, nothing is being drawn. I actually cannot figure out what is wrong with my code. I decided to create a small application to test that and again nothing is being drawn. The small code I wrote to test it is shown below:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();DrawText(); } private void DrawText() { Graphics grfx = panel.CreateGraphics(); grfx.DrawString("Problem drawing text on Panel", panel.Font, Brushes.Black, 50, 50); grfx.Dispose(); } }
}
The variable 'panel' is an object of Panel which has been placed on the form with a Dock property 'Fill'. After compiling the text is not drawn. I don't know what I am doing wrong. Please help.
As Pete says, this specific case is because you're drawing on the panel before the form finishes loading, and therefore before the panel hits the screen and repaints itself, so anything you are doing may work but you'll never see it. (Actually I'm a bit surprised CreateGraphics doesn't throw an exception at that stage.) Why do you think you need to paint stuff outside a Paint event handler? There are a few specialist cases where that can be useful, but for 99% of all custom painting you want to do it in Paint, and I would expect that you should also be doing it there.
-
The most obvious thing here is that your form hasn't actually finished loading yet, and you are attempting to draw the text once and once only (before the form is actually rendered). What you need to do is draw the string in the Paint event handler. As you are drawing this in a panel, you would hook into the paint event handler on the panel like this:
private void panel_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawString("Problem drawing text on panel", panel.Font, Brushes.Black, 50, 50);
}*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
My blog | My articles | MoXAML PowerToys | Mole 2010 - debugging made easier - my favourite utility
-
As Pete says, this specific case is because you're drawing on the panel before the form finishes loading, and therefore before the panel hits the screen and repaints itself, so anything you are doing may work but you'll never see it. (Actually I'm a bit surprised CreateGraphics doesn't throw an exception at that stage.) Why do you think you need to paint stuff outside a Paint event handler? There are a few specialist cases where that can be useful, but for 99% of all custom painting you want to do it in Paint, and I would expect that you should also be doing it there.
I was drawing the text outside the Paint event because the Panel is created in a different class while the function that draws the text is found in another class in the application I am writing (Not the example shown as a test). But I think I should do it in a Paint event. I want to install a Paint event for the Panel in the class within which the function that draws the text is implemented. Yet to do it but I hope that will work. Thanks.
-
I was drawing the text outside the Paint event because the Panel is created in a different class while the function that draws the text is found in another class in the application I am writing (Not the example shown as a test). But I think I should do it in a Paint event. I want to install a Paint event for the Panel in the class within which the function that draws the text is implemented. Yet to do it but I hope that will work. Thanks.
One way to handle this is to create a list of items you want to paint (ordered by the order you want to paint them), and have each one use it's own paint method. Then you just iterate over this list in the paint event and call the appropriate draw. I would typically do something like this:
public abstract class PaintBase
{
public void Draw(Graphics graphics)
{
OnDraw(Graphics graphics);
}protected abstract OnDraw(Graphics graphics);
}Then, you derive your classes from this:
public class PanelText : PaintBase
{
public Font DrawFont { get; set; }
public string Text { get; set; }
protected override OnDraw(Graphics graphics)
{
graphics.DrawString(Text, DrawFont, Brushes.Black, 50, 50);
}
}Then, in your form, create a list of type
PaintBase
and add what you need to it, as in:private List<PaintBase> paintables = new List<PaintBase>();
private void AddPaintables()
{
PanelText panelText = new PanelText();
panelText.DrawFont = panel.Font;
panelText.Text = "Problem drawing text on panel";
paintables.Add(panelText);
}Finally, in your paint handler, all you would do is iterate like this:
foreach (PaintBase item in paintables)
{
item.Draw(e.Graphics);
}This is a very rough implementation - it's missing a lot of error handling, validation, etc, but on the whole, you should be able to get the idea. Note that I've just knocked this up in the message editor, so I apologise if the syntax isn't 100%; it should serve to get you started though.
*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
My blog | My articles | MoXAML PowerToys | Mole 2010 - debugging made easier - my favourite utility
-
Thanks Hanlon! Looks like I cannot avoid Paint handling for the Panel control for it to work. I will try that.
It's best to hang your painting code in the Paint event. Windows will tell you when to paint your form as that can be at any time, even you don't expect it in your code. It's far better to do it that way instead of trying to figure out why it appears as though your painting code work most of the time, but not at others. For example, in your original code, your painting code would draw the text on the panel, but when the user drags another window over the top of the panel and then removes it, your text will be gone. Windows will tell you that your forms and controls need to be repainted via the Paint event. If you don't hang your drawing code from there, you'll end up with all kinds of painting issues you can't figure out.
A guide to posting questions on CodeProject[^]
Dave Kreskowiak -
One way to handle this is to create a list of items you want to paint (ordered by the order you want to paint them), and have each one use it's own paint method. Then you just iterate over this list in the paint event and call the appropriate draw. I would typically do something like this:
public abstract class PaintBase
{
public void Draw(Graphics graphics)
{
OnDraw(Graphics graphics);
}protected abstract OnDraw(Graphics graphics);
}Then, you derive your classes from this:
public class PanelText : PaintBase
{
public Font DrawFont { get; set; }
public string Text { get; set; }
protected override OnDraw(Graphics graphics)
{
graphics.DrawString(Text, DrawFont, Brushes.Black, 50, 50);
}
}Then, in your form, create a list of type
PaintBase
and add what you need to it, as in:private List<PaintBase> paintables = new List<PaintBase>();
private void AddPaintables()
{
PanelText panelText = new PanelText();
panelText.DrawFont = panel.Font;
panelText.Text = "Problem drawing text on panel";
paintables.Add(panelText);
}Finally, in your paint handler, all you would do is iterate like this:
foreach (PaintBase item in paintables)
{
item.Draw(e.Graphics);
}This is a very rough implementation - it's missing a lot of error handling, validation, etc, but on the whole, you should be able to get the idea. Note that I've just knocked this up in the message editor, so I apologise if the syntax isn't 100%; it should serve to get you started though.
*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
My blog | My articles | MoXAML PowerToys | Mole 2010 - debugging made easier - my favourite utility
Very cool, Pete, this to me exemplifies one of the cases of "gems submerging in the forums," where the post, imho, deserves elevation to some "archived Valhalla," without requiring the author to write a Tip/Trick or article. As you know, I have been commenting on issues like this in the "Buggs and Suggs" forum. best, Bill
"The first principle is that you must not fool yourself, and you are the easiest person to fool." Richard Feynman
-
Hi everyone. I'm trying to draw text of string on a panel control outside the Paint event but surprisingly, nothing is being drawn. I actually cannot figure out what is wrong with my code. I decided to create a small application to test that and again nothing is being drawn. The small code I wrote to test it is shown below:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();DrawText(); } private void DrawText() { Graphics grfx = panel.CreateGraphics(); grfx.DrawString("Problem drawing text on Panel", panel.Font, Brushes.Black, 50, 50); grfx.Dispose(); } }
}
The variable 'panel' is an object of Panel which has been placed on the form with a Dock property 'Fill'. After compiling the text is not drawn. I don't know what I am doing wrong. Please help.
Hi
Dan_K
, To draw object under any control, you must implement the event "OnPaint". You can use this code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();panel.Paint += new PaintEventHandler(panel\_Paint); } private void void panel\_Paint(object sender, PaintEventArgs e) { e.Graphics.DrawString("Problem drawing text on Panel", panel.Font, Brushes.Black, 50, 50); } }
}