How to draw image on tabPage overlapping buttons
Black circles(DrawImage on tabPage8_Paint) should be above the buttons:
http://rghost.ru/6sVBl8mkh/image.png
It must be so:
http://rghost.ru/6BgDM77pq/image.png
My code
public SibModem() {
InitializeComponent();
tabPage8.Paint += new PaintEventHandler(tabPage8_Paint);
gettime();
this.SizeChanged += new EventHandler(this.SibModem_Resize);
}
protected void tabPage8_Paint(object sender, PaintEventArgs e) {
GraphicsUnit units = GraphicsUnit.Pixel;
base.OnPaint(e);
Graphics g = e.Graphics;
g.DrawImage(bg, 0, 0);
Rectangle srcRect = new Rectangle(offsetant, 0, w, h);
g.DrawImage(anten, x, y, srcRect, units);
Rectangle ussdwaitRect = new Rectangle(offsetussd, 0, 64, 64);
g.DrawImage(ussdwait, usx, usy, ussdwaitRect, units);
}
You can't draw above nested controls, so you need to draw parts of the image onto those Buttons.
So combine drawing onto the tabpage and drawing onto the buttons you need to adorn!
Here is a simple example using only one image:
A few class level variables:
Point iLoc = Point.Empty;
Image img = null;
List<Button> overlaidButtons = new List<Button>();
Prepare the image, its position and a list of possibly overlaid buttons:
public Form1()
{
InitializeComponent();
string imgN = #"d:\scrape\gears\gear_12x4hand.png";
img = Image.FromFile(imgN);
iLoc = new Point(100, 100);
overlaidButtons.AddRange(new []{button10,button11,button12,button13 });
// each button calls the same paint event
foreach (Button btn in overlaidButtons) btn.Paint += btn_Paint;
}
The common Paint event. We calculate the relative position of the image..
void btn_Paint(object sender, PaintEventArgs e)
{
Button btn = sender as Button;
e.Graphics.DrawImage(img, new Point(iLoc.X - btn.Left, iLoc.Y - btn.Top));
}
Note that if the Buttons are nested deeper you need to adapt the calculation to include all levels of nesting!
The TabPage Paint event:
private void tabPage5_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(img, iLoc);
}
Try BringToFront method, it brings the control to the front of the z-order.
See this reference on MSDN: https://msdn.microsoft.com/en-us/library/system.windows.forms.control.bringtofront(v=vs.110).aspx
Related
I'm currently working on windows form application where I have two forms; form1 and form2. There is a button inside form1 which opens form2 when clicked and what I want is to create a rectangle inside a panel of form1 when a button inside Form2 is clicked. I put some code to create rectangle inside the button click event of form2, but it showed nothing when clicked. However, whenever I put the draw.rectangle method inside the same form where button is clicked, it work, but differently it doesn't
Here's the code inside form1
private void btnSave_Click(object sender, EventArgs e)
{
Layoutsetting a = new Layoutsetting();
a.ShowDialog();
}
public void DrawObject()
{
Graphics g = panel1.CreateGraphics();
Rectangle rect = new Rectangle(10, 10, 80, 90);
rect.Inflate(-10, -10);
g.DrawRectangle(black, rect);
g.FillRectangle(Brushes.BlueViolet, rect);
StringFormat f = new StringFormat();
f.LineAlignment = StringAlignment.Center;
f.Alignment = StringAlignment.Center;
g.DrawString("Hello", this.Font, Brushes.GhostWhite, rect, f);
panel1.Refresh();
}
This is the code inside form2
private void btnConfirm_Click(object sender, EventArgs e)
{
Form1.Default.DrawObject();
this.Close();
}
The problem is not with drawing rectangle, the panel paint event fires whenever even a slightest part of the panel were hidden (for example a part of it was behind another form) and redraws the panel, so the rectangle disappears (but when it is the active form which paint event doesn't fire, the rectangle will be drawn and will not be cleared unless you do something that panel needs to be redrawn.).
Easy Solution:
Create an image of recangle and use it as background image when needed, instead of drawing it.
Another Solution:
add a property to your form (or your panel):
public bool NeedsToBeDrawn {get; set;}
instead of this line of code:
Form1.Default.DrawObject();
just set the property to true:
Form1.NeedsToBeDrawn = true;
and move your code to your panel's paint event:
private void panel1_Paint(object sender, PaintEventArgs e)
{
if(NeedsToBeDrawn)
{
Rectangle rect = new Rectangle(10, 10, 80, 90);
rect.Inflate(-10, -10);
e.Graphics.DrawRectangle(black, rect);
e.Graphics.FillRectangle(Brushes.BlueViolet, rect);
StringFormat f = new StringFormat();
f.LineAlignment = StringAlignment.Center;
f.Alignment = StringAlignment.Center;
e.Graphics.DrawString("Hello", this.Font, Brushes.GhostWhite, rect, f);
}
}
You have to add a method to Paint:
panel1.Paint += new System.Windows.Forms.PaintEventHandler(this.draw);
private void draw(object sender, PaintEventArgs e)
{
if(buttonClicked) {
Graphics g = e.Graphics;
//...
}
}
I've been reading stackoverflow for a while now just to learn, and I've come across a situation where I can finally ask a question. I'm making a Simon Says type memory game, where I flash shapes at the user, and the user has to click a button in the same order the shapes were shown to them. I want to draw the shape that I'm drawing on the screen within the button that they are clicking because it's much easier to remember and compare shapes to shapes rather than shapes to a button that says the shapes name.
Hopefully my question is clear, and thanks for taking a look!
Yes, you can set the Image property of Button. Alternatively, you can draw non-rectangular buttons, that is, buttons of any shape. The following code demonstrates both techniques:
using System;
using System.Drawing;
using System.Windows.Forms;
class ShapeButton : Button {
public Action<PaintEventArgs> DoPaint { get; set; }
protected override void OnPaint(PaintEventArgs e) {
if (DoPaint != null) { DoPaint(e); }
}
}
static class Program {
static void Main() {
// Ellipse button
ShapeButton ellipseButton = new ShapeButton();
ellipseButton.Location = new Point(10, 10);
ellipseButton.Size = new Size(80, 80);
ellipseButton.DoPaint = delegate(PaintEventArgs e) {
Graphics graphics = e.Graphics;
SolidBrush brush1 = new SolidBrush(SystemColors.ButtonFace);
graphics.FillRectangle(brush1, 0, 0, ellipseButton.Width, ellipseButton.Height);
SolidBrush brush2 = new SolidBrush(Color.Red);
graphics.FillEllipse(brush2, 0, 0, ellipseButton.Width, ellipseButton.Height);
};
ellipseButton.Click += delegate(object sender, EventArgs e) {
MessageBox.Show("Ellipse!");
};
// Triangle button
ShapeButton triangleButton = new ShapeButton();
triangleButton.Location = new Point(100, 10);
triangleButton.Size = new Size(80, 80);
triangleButton.DoPaint = delegate(PaintEventArgs e) {
Graphics graphics = e.Graphics;
SolidBrush brush1 = new SolidBrush(SystemColors.ButtonFace);
graphics.FillRectangle(brush1, 0, 0, triangleButton.Width, triangleButton.Height);
SolidBrush brush2 = new SolidBrush(Color.Green);
Point[] points = {
new Point(triangleButton.Width / 2, 0),
new Point(0, triangleButton.Height),
new Point(triangleButton.Width, triangleButton.Height)
};
graphics.FillPolygon(brush2, points);
};
triangleButton.Click += delegate(object sender, EventArgs e) {
MessageBox.Show("Triangle!");
};
// Star button (using image)
Button starButton = new Button();
starButton.Location = new Point(190, 10);
starButton.Size = new Size(80, 80);
starButton.Image = new Bitmap("Star.png");
starButton.Click += delegate(object sender, EventArgs e) {
MessageBox.Show("Star!");
};
// The form
Form form = new Form();
form.Text = "Shape Button Test";
form.ClientSize = new Size(280, 100);
form.Controls.Add(ellipseButton);
form.Controls.Add(triangleButton);
form.Controls.Add(starButton);
form.ShowDialog();
}
}
Result (after clicking on the triangle button):
In winforms to change the button's image at runtime you can use something like this:
button1.Image = new Bitmap(Image.FromFile(#"Pictures\Koala.jpg"));
It should be added to event handler. For example if you want to show the image when the button is clicked you subscribe to Click event of the button and add the code into the handler method:
private void button1_Click(object sender, EventArgs e)
{
button1.Image = new Bitmap(Image.FromFile(#"Pictures\Koala.jpg"));
}
In my example,
I have a pictureBox to show, two buttons, one to control, one to be drawn.
//odd display, even draw
int count = 0;
Image storePicture;
//whenever the background image changed,store it
private void pictureBoxShow_BackgroundImageChanged(object sender, EventArgs e)
{
//you can stored to a Image array if you have series pictures to show
storePicture = pictureBoxShow.BackgroundImage;
}
private void buttonControl_Click(object sender, EventArgs e)
{
count++;
//odd show picture, even draw picture on button
if (count % 2 == 1)
pictureBoxShow.BackgroundImage = new Bitmap("shapes.JPG");
else
{
//in case you want to clear text on the button
buttonDrawn.Text = null;
//recreate the picture so that it fit the button size
buttonDrawn.Image = new Bitmap(storePicture, new Size(buttonDrawn.Width, buttonDrawn.Height));
}
}
Please remember to attach the handlers to corresponding events. ^^
Why not using PictureBox instead of Buttons.
you have just to add your task to its event/OnClick
Of course you can load any Image to any PictureBox in runtime
The code above is great, however you can click outside the circle within a square containing the circle and get the click event.
If you want to capture the click only if the user clicks inside the shape you have to set the region property with something like this
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
GraphicsPath gp = new GraphicsPath();
gp.AddEllipse(0, 0, 100, 100);
Button1.Region = new Region(gp);
}
}
I have a pictureBox1 with image inside and when i click on it its drawing points.
Now i added a reset button i called it when i click on it its should clear all the drawings i did on the pictureBox and leavethe image inside without the drawings on it.
I did:
private void button4_Click(object sender, EventArgs e)
{
Graphics graphics;
graphics = pictureBox1.CreateGraphics();
graphics.DrawImage(pictureBox1.Image, 0, 0);
}
So i draw a lot of points on pictureBox1 then click the button and all points are gone but then once i click on the picturebox1 again i see also the new points but also the old points i did before the clearing.
How can i clear the old drawings so it wont show up on the next clicks ?
This is the paint event: Moved the paint event to a new class:
public static void Paint(List<PointF> pb1points, GraphicsPath pb1gp, Point movingPoint, PictureBox pictureBox1, Graphics e)
{
e.Clear(Color.White);
e.DrawImage(pictureBox1.Image, movingPoint);
Pen p;
p = new Pen(Brushes.Green);
foreach (PointF pt in pb1points)
{
e.FillEllipse(Brushes.Red, pt.X, pt.Y, 3f, 3f);
}
using (Pen pp = new Pen(Color.Green, 2f))
{
pp.StartCap = pp.EndCap = LineCap.Round;
pp.LineJoin = LineJoin.Round;
e.DrawPath(pp, pb1gp);
}
}
You can try using Graphics.Clear().
Reference: http://msdn.microsoft.com/en-us/library/system.drawing.graphics.clear(v=vs.110).aspx
setting the Image property to null should work.
picBox.Image = null;
Ii it's not worked ,you might be used the InitialImage property to display your image.
pictBox.InitialImage = null;
Please refer the link:
Clear image on picturebox
This is working:
private void button4_Click(object sender, EventArgs e)
{
Graphics graphics;
graphics = pictureBox1.CreateGraphics();
graphics.DrawImage(pictureBox1.Image, 0, 0);
pb1points = new List<PointF>();
}
I have a Panel called panel1 and I am trying to draw a line on my panel1 using this code:
var g = panel1.CreateGraphics();
var p = new Pen(Color.Black, 3);
var point1 = new Point(234,118);
var point2 = new Point(293,228);
g.DrawLine(p, point1, point2);
But nothing is showing up. Any ideas? This is in a windows form.
Handle the Panel's Paint event and put it in there. What's happening is that it's being drawn once in the constructor but then being drawn over in the Paint event everytime it's called.
private void panel1_Paint(object sender, PaintEventArgs e)
{
base.OnPaint(e);
using(Graphics g = e.Graphics)
{
var p = new Pen(Color.Black, 3);
var point1 = new Point(234,118);
var point2 = new Point(293,228);
g.DrawLine(p, point1, point2);
}
}
Put it in some event after the form has been created and shown on the screen and it should work fine.
It's best to put it in the Paint event, as keyboardP stated, but it will not show up if called before the form is shown on the screen.
To test this you can add a button and add the code to the click event:
private void button1_Click(object sender, EventArgs e)
{
using (Graphics g = panel1.CreateGraphics())
{
g.DrawLine(new Pen(Color.Back, 3), new Point(234,118), new Point(293,228));
}
}
To see your drawing - you can simply make a button with a Click Event and draw when the button is clicked. For example:
private void btnDraw_Click(object sender, EventArgs e)
{
Graphics dc = drawingArea.CreateGraphics();
Pen BlackPen = new Pen(Color.Black, 2);
dc.DrawLine(BlackPen, 0, 0, 200, 200);
BlackPen.Dispose();
dc.Dispose();
}
Oh, and by the way "drawingArea" is the (Name) of either a PictureBox or Panel you have added to your form (to draw in it).
If you follow the other answers and still your drawings are not showing up try removing all controls from the control that is being drawn to. The other controls may be covering whatever you are trying to draw.
private void button2_Click(object sender, EventArgs e)
{
panel1.Paint += new PaintEventHandler(
(object sender1, PaintEventArgs e1) => {
var p = new Pen(Color.Black, 3);
var point1 = new Point(234, 118);
var point2 = new Point(293, 228);
e1.Graphics.DrawLine(p, point1, point2);
}
);
panel1.Invalidate();
}
i have one picture showing of the human body and i want to use shapes to locate the injuries of the patient. all the shapes will shows off when the user click button. right now im testing with only one shape.
here is my code.
private void button7_Click_4(object sender, EventArgs e)
{
Graphics g = this.CreateGraphics();
g.Clear(this.BackColor);
Image img = Image.FromFile("C:\\Users\\HDAdmin\\Pictures\\humanbody\\effect2.png");
g.DrawImage(img, 0, 0, img.Height, img.Width);
g.Dispose();
}
right now, the shape appear at the back of the image. so how i want to make the shape appear in front of the picture?
Couple of issues.
1) Painting should happen in a paint event. Do not use CreateGraphics since that will only be a temporary drawing.
2) Your DrawImage width and height arguments are reversed.
3) It doesn't look like you are painting the PictureBox control that you have on the form:
private Image img;
public Form1() {
InitializeComponent();
button1.Click += button1_Click;
pictureBox1.Paint += pictureBox1_Paint;
}
void button1_Click(object sender, EventArgs e) {
img = = Image.FromFile("C:\\Users\\HDAdmin\\Pictures\\humanbody\\effect2.png");
pictureBox1.Invalidate();
}
void pictureBox1_Paint(object sender, PaintEventArgs e) {
e.Graphics.Clear(pictureBox1.BackColor);
if (img != null) {
e.Graphics.DrawImage(img, 0, 0, img.Width, img.Height);
//Draw test shape:
e.Graphics.DrawRectangle(Pens.Red, new Rectangle(10, 10, 20, 60));
}
}
I think you should first get graphics of human image and then draw shape image on it. Some thing like that :
Image img = Image.FromFile("C:\\Users\\HDAdmin\\Pictures\\humanbody\\effect2.png");
Graphics g = Graphics.FromImage ( img );
g.DrawImage(ShapeImage, 0, 0, 30, 30); // you can set your required x,y,width,height