I have created a venn diagram which looks like this,
I have also created regions for handling clicks on each part of venn. Left / Right and common two parts. Here is the code I have,
private void panelControlVennDiagram_Paint(object sender, PaintEventArgs e)
{
Rectangle leftVenn = new Rectangle(20, 50, 130, 130);
Rectangle rightVenn = new Rectangle(60, 50, 130, 130);
commonRegion = new Region();
Pen pen = new Pen(Color.Black,3);
using (Brush brushLeft = new SolidBrush(leftVennColor))
{
ellipseLeftOnlyPath.AddEllipse(leftVenn);
leftOnlyRegion = new Region(ellipseLeftOnlyPath);
e.Graphics.FillEllipse(brushLeft, leftVenn);
e.Graphics.DrawEllipse(pen, leftVenn);
brushLeft.Dispose();
}
using (Brush brushRight = new SolidBrush(rightVennColor))
{
ellipseRightOnlyPath.AddEllipse(rightVenn);
rightOnlyRegion = new Region(rightVenn);
e.Graphics.FillEllipse(brushRight, rightVenn);
e.Graphics.DrawEllipse(pen, rightVenn);
brushRight.Dispose();
}
using (GraphicsPath circle_path = new GraphicsPath())
{
circle_path.AddEllipse(leftVenn);
commonRegion.Intersect(circle_path);
}
using (GraphicsPath circle_path = new GraphicsPath())
{
circle_path.AddEllipse(rightVenn);
commonRegion.Intersect(circle_path);
}
leftOnlyRegion.Exclude(commonRegion);
rightOnlyRegion.Exclude(commonRegion);
using (Brush brushCommon = new SolidBrush(commonColor))
{
e.Graphics.FillRegion(brushCommon, commonRegion);
brushCommon.Dispose();
}
using (Brush brushLeftOnly = new SolidBrush(leftRightCommonColor))
{
ellipseLeftRightCommonPath.AddEllipse(65, 80, 35, 40);
e.Graphics.FillEllipse(brushLeftOnly, 65, 80, 35, 40);
e.Graphics.DrawEllipse(pen, 65, 80, 35, 40);
brushLeftOnly.Dispose();
}
using (Brush brushRightOnly = new SolidBrush(rightLeftCommonColor))
{
ellipseRightLeftCommonPath.AddEllipse(105, 110, 35, 40);
e.Graphics.FillEllipse(brushRightOnly, 105, 110, 35, 40);
e.Graphics.DrawEllipse(pen, 105, 110, 35, 40);
brushRightOnly.Dispose();
}
Brush brush = new SolidBrush(Color.Black);
Font stringFont = new Font("Calibri", 9, FontStyle.Bold);
Font stringFontCommon = new Font("Calibri", 8, FontStyle.Bold);
e.Graphics.DrawString(leftValue.ToString(), stringFont, brush, 40, 90);
e.Graphics.DrawString(rightValue.ToString(), stringFont, brush, 160, 90);
e.Graphics.DrawString(leftRightValue.ToString(), stringFontCommon, brush, 70, 115);
e.Graphics.DrawString(rightLeftValue.ToString(), stringFontCommon, brush, 110, 115);
brush.Dispose();
stringFont.Dispose(); stringFontCommon.Dispose();
pen.Dispose();
}
This is to handle the mouse clicks. Basically I want to have a click handled only on left / right parts and not their intersection. But even with this I dont get the message box. Sometimes if I put a break point it does hit messagebox code but sometimes not.
private void panelControlVennDiagram_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
if (ellipseLeftRightCommonPath.IsVisible(e.Location))
MessageBox.Show("Left - Right Common");
else if (ellipseRightLeftCommonPath.IsVisible(e.Location))
MessageBox.Show("Right - Left Common");
else if (leftOnlyRegion.IsVisible(e.Location))
MessageBox.Show("Left Only");
else if (rightOnlyRegion.IsVisible(e.Location))
MessageBox.Show("Right Only");
}
}
Whats wrong here? Please help.
I used directly regions rather than using GraphicsPath.. It works .
leftOnlyRegion = new Region(leftVenn);
Related
Ok, I have got a printDocument1_PrintPage method which is supposed to print out the contents of a ListView. During execution, the method only prints out the first page. Could someone help me to printout the remaining page(s)?
I have identified the end of the first page via the variable ypos and set the property e.HasMorePages = true.
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e){
Graphics graphics = e.Graphics;
int ypos = 78;
Font f1 = new Font("Arial", 14, FontStyle.Bold, GraphicsUnit.Pixel);
Brush brush = new SolidBrush(Color.LightSlateGray);
graphics.FillRectangle(brush, new Rectangle(10, 10, 770, 50));
Pen blackpen = new Pen(Color.Black);
Pen graypen = new Pen(Color.LightGray);
Pen redpen = new Pen(Color.Red);
graphics.DrawRectangle(blackpen, new Rectangle(10, 10, 770, 50));
Brush B = new SolidBrush(listView1.ForeColor);
graphics.DrawLine(blackpen, 10, 10, 10, 1132);
graphics.DrawString("FORENAME", f1, Brushes.Black, new Point(20, 25));
graphics.DrawLine(blackpen, 130, 10, 130, 1132);
graphics.DrawString("SURNAME", f1, Brushes.Black, new Point(140, 25));
graphics.DrawLine(blackpen, 290, 10, 290, 1132);
graphics.DrawString("EXT.", f1, Brushes.Black, new Point(300, 25));
graphics.DrawLine(blackpen, 380, 10, 380, 1132);
graphics.DrawString("JOB TITLE", f1, Brushes.Black, new Point(410, 25));
graphics.DrawLine(blackpen, 780, 10, 780, 1132);
int[] X = { 15, 140, 300, 390, 720 };
int Y = 60;
f1 = listView1.Font;
for (int I = 0; I < listView1.Items.Count; I++){
for (int J = 0; J < listView1.Items[I].SubItems.Count - 1; J++){
graphics.DrawString(listView1.Items[I].SubItems[J].Text, f1, B, X[J], Y);
}
Y += f1.Height;
graphics.DrawLine(graypen, 10, ypos, 780, ypos);
ypos = ypos + 17;
if (ypos > 1132){
e.HasMorePages = true;
return;
}
}
graphics.Dispose();
}
i am using the bitmap method to print the DataGridView.
How to split the bitmap on two pages if the this.dgvTheory.Height is bigger than 500?Everything should stay on the first page,except the bitmap which can go on second page if it's big.
Edited: The rest of the image should go on the 2nd page.
Thanks in advance.
private void button1_Click(object sender, EventArgs e)
{
int height = dgvTheory.Height;
dgvHistTheoCust.Height = dgvTheory.RowCount * dgvTheory.RowTemplate.Height;
bitmap = new Bitmap(960, this.dgvTheory.Height);
dgvTheory.DrawToBitmap(bitmap, new Rectangle(0, 0, 960, this.dgvTheory.Height));
dgvTheory.Height = height;
printPreviewDialog1.Document = printDocument1;
printPreviewDialog1.ShowDialog();
}
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
this.printDocument1.DefaultPageSettings.Landscape = true;
using (Font fnt1 = new Font("Segoe UI", 12f, FontStyle.Regular))
{
using (Font fnt2 = new Font("Arial", 13f, FontStyle.Bold))
{
e.Graphics.DrawString("just a text", fnt2, Brushes.Black, new RectangleF(new PointF(500f, 10f), new SizeF(300f, 20f)));
e.Graphics.DrawRectangle(Pens.Black, 50, 5, 1000, 30);
e.Graphics.DrawRectangle(Pens.Black, 50, 35, 1000, 30);
e.Graphics.DrawString("just a test", fnt2, Brushes.Black, new RectangleF(new PointF(280f, 40f), new SizeF(700f, 20f)));
e.Graphics.DrawRectangle(Pens.Black, 50, 70, 300, 20);
e.Graphics.DrawString("some data :", fnt1, Brushes.Black, new RectangleF(new PointF(55f, 70f), new SizeF(500f, 20f)));
e.Graphics.DrawRectangle(Pens.Black, 50, 90, 300, 20);
e.Graphics.DrawString("some data :", fnt1, Brushes.Black, new RectangleF(new PointF(55f, 90f), new SizeF(300f, 20f)));
e.Graphics.DrawRectangle(Pens.Black, 350, 70, 700, 20);
e.Graphics.DrawString("str", fnt1, Brushes.Black, new RectangleF(new PointF(600f, 70f), new SizeF(300f, 20f)));
e.Graphics.DrawRectangle(Pens.Black, 350, 90, 700, 20);
e.Graphics.DrawString("str", fnt1, Brushes.Black, new RectangleF(new PointF(600f, 90f), new SizeF(300f, 20f)));
e.Graphics.DrawRectangle(Pens.Black, 50, 110, 300, 20);
e.Graphics.DrawRectangle(Pens.Black, 350, 110, 700, 20);
e.Graphics.DrawString("some data :", fnt1, Brushes.Black, new RectangleF(new PointF(55, 110), new SizeF(300f, 20f)));
e.Graphics.DrawString("str", fnt1, Brushes.Black, new RectangleF(new PointF(600, 110), new SizeF(300f, 20f)));
e.Graphics.DrawImage(bitmap, 50, 135);
e.Graphics.DrawRectangle(Pens.Black, 50, 640, 300, 20);
e.Graphics.DrawString("some data :", fnt1, Brushes.Black, new RectangleF(new PointF(50, 640), new SizeF(300f, 20f)));
e.Graphics.DrawRectangle(Pens.Black, 350, 640, 700, 20);
e.Graphics.DrawString("int", fnt1, Brushes.Black, new RectangleF(new PointF(700, 640), new SizeF(300f, 20f)));
e.Graphics.DrawString("some data....", fnt1, Brushes.Black, new RectangleF(new PointF(50, 660), new SizeF(1000f, 70f)));
e.Graphics.DrawString("my sign goes here", fnt1, Brushes.Black, new RectangleF(new PointF(650, 730), new SizeF(300f, 20f)));
}
}
}
Printing on multiple page is controlled by two indicators:
the internal flag e.HasMorePages tells the system to re-enter the PrintPage method once more after you return from it.
some external flag you need to set up tells you which page and/or which content you are supposed to print next.
The internal flag is rather simple but you need to know that it wil be reset whenever you enter the method!
Your external flag can be anything you want, a bool or a number or it can even be implicit, like the state of a queue.
In your case a simple bool will be enough, but for more complex print jobs one may want e.g. an index into a list of items to print..
Let's call your flag printImageOnPageTwo. Declare it at class level:
bool printImageOnPageTwo = false;
Now you can check for it to know if you should enter the part that prints page one or skip it and print the image to the top of page two..:
private void printDocument1_PrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
{
this.printDocument1.DefaultPageSettings.Landscape = true;
if (!printImageOnPageTwo )
using (Font fnt1 = new Font("Segoe UI", 12f, FontStyle.Regular))
using (Font fnt2 = new Font("Arial", 13f, FontStyle.Bold))
{
e.Graphics.DrawString("just a text", fnt2,.....);
...
...
if (dgvTheory.Height <= than 500)
e.Graphics.DrawImage(...., y_InTheMiddle)
else
{
printImageOnPageTwo = true: // set our flag
e.HasMorePages = true; // set the system flag
return; // quit the routine
}
} // end if !printImageOnPageTwo
else e.Graphics.DrawImage(...., y_AtTheTop);
printImageOnPageTwo = false; // reset our flag
}
I have created some Ellipses on Windows form
I want that selectable while mouse over and if i select any ellipse it will delete from Window
Here some code for create ellipse in c#
public void DrawCircle_Paint(object sender, PaintEventArgs e)
{
Pen pen = new Pen(Color.Black, 3); Graphics gr = this.CreateGraphics(); gr.DrawEllipse(pen, 40, 45, 20, 20);
Pen pen2 = new Pen(Color.Black, 3); Graphics gr1 = this.CreateGraphics(); gr.DrawEllipse(pen2, 30, 25, 38, 20);
Pen pen3 = new Pen(Color.Black, 3); Graphics gr2 = this.CreateGraphics(); gr.DrawEllipse(pen3, 35, 36, 68, 15);
Pen pen4 = new Pen(Color.Black, 3); Graphics gr3 = this.CreateGraphics(); gr.DrawEllipse(pen4, 50, 60, 67, 35);
}
You could use
this.Invalidate();
That should clear them....
Either that, or
Graphics.Clear();
Edit:
Actually, another method be to have a boolean inside of your mouse on hover, and use that to dictate when to draw the elipse/not. As a general note, you should be putting the elipse drawing in an override of onpaint. Right now, currently, if you were to invalidate the screen (either by you, or by Windows), your shapes will disappear. An Example using on paint.
bool paint = false;
protected override void OnPaint(object sender, PaintEventArgs e)
{
if (paint)
{
Pen pen = new Pen(Color.Black, 3); Graphics gr = this.CreateGraphics(); gr.DrawEllipse(pen, 40, 45, 20, 20);
Pen pen2 = new Pen(Color.Black, 3); Graphics gr1 = this.CreateGraphics(); gr.DrawEllipse(pen2, 30, 25, 38, 20);
Pen pen3 = new Pen(Color.Black, 3); Graphics gr2 = this.CreateGraphics(); gr.DrawEllipse(pen3, 35, 36, 68, 15);
Pen pen4 = new Pen(Color.Black, 3); Graphics gr3 = this.CreateGraphics(); gr.DrawEllipse(pen4, 50, 60, 67, 35);
}
}
I don't remember the specific paramters for it, but in your OnMouseHover (where you want to turn off your elipse)
OnMouseHover(){
...
paint = false;
this.Invalidate();
}
I'd like to know how to paint User Control with background Transparency even if the user control is raised or moved at runtime.
my code is
private void UserControl1_Paint(object sender, PaintEventArgs e)
{
var g = e.Graphics;
g.Clear(Color.White);
g.SmoothingMode = SmoothingMode.HighQuality;//可以反锯齿
var rectBound = new Rectangle(0, 0, Width-1, Height-1);
var b = new SolidBrush(Color.FromArgb(0, 122, 204));
var rect = new Rectangle(2, 2, Width - 4, Height - 4);
if(!_isSelected)//FillRectangle
g.FillEllipse(b, rectBound);
else
g.FillEllipse(b, rect);
var pen = new Pen(Color.Yellow);
pen.DashStyle = DashStyle.DashDot;
g.DrawLine(pen,10,10,100,10);
pen.DashStyle = DashStyle.Dash;
g.DrawLine(pen, 10, 15, 100, 15);
pen.DashStyle = DashStyle.DashDotDot;
g.DrawLine(pen, 10, 20, 100, 20);
pen.DashStyle = DashStyle.Dot;
g.DrawLine(pen, 10, 25, 100, 25);
pen.DashStyle = DashStyle.Solid;
g.DrawLine(pen, 10, 30, 100, 30);
if (_isSelected)
{
pen = new Pen(Color.Black) { DashStyle = DashStyle.Dot, Width = 1 };
g.DrawRectangle(pen, rectBound);
}
}
and demo picture here
there will be a lot of User Controls Created at runtime,some of them maybe overlapped,then it should be clear the user control's background.how to do that?
I am trying to move a drawn graphics item, I can draw them just fine. but when I try to move it, it just draws another item over the original. I have tried Invalidate, and pictureBox1.Invalidate. still no luck just prints both items to the pictureBox.
Thanks for any suggestions.
private void button1_Click(object sender, EventArgs e)
{
count++;
button1.Text = "Move";
if (count == 1)
{
car();
}
else if (count == 2)
{
car1();
}
}
public void car()
{
Invalidate();
g = pictureBox1.CreateGraphics();
g.DrawEllipse(pen1, 50, 125, 30, 30);
g.DrawEllipse(pen1, 150, 125, 30, 30);
g.DrawRectangle(pen2, 45, 75, 140, 50);
g.DrawLine(pen2, 65, 75, 80, 35);
g.DrawLine(pen2, 80, 35, 140, 35);
g.DrawLine(pen2, 140, 35, 160, 75);
// Create string to draw.
String drawString = "Price: "+(cost).ToString("C");
// Create font and brush.
Font drawFont = new Font("Arial", 16);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// Create point for upper-left corner of drawing.
PointF drawPoint = new PointF(50, 95);
// Draw string to screen.
g.DrawString(drawString, drawFont, drawBrush, drawPoint);
}
public void car1()
{
Invalidate();
g = pictureBox1.CreateGraphics();
g.DrawEllipse(pen1, 50 + m, 125, 30 , 30 );
g.DrawEllipse(pen1, 150 + m, 125, 30 , 30);
g.DrawRectangle(pen2, 45 + m, 75, 140, 50 );
g.DrawLine(pen2, 65 + m, 75, 80 + m, 35);
g.DrawLine(pen2, 80 + m, 35, 140 + m, 35);
g.DrawLine(pen2, 140 + m, 35, 160 + m, 75);
// Create string to draw.
String drawString = "Price: " + (cost).ToString("C");
// Create font and brush.
Font drawFont = new Font("Arial", 16);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// Create point for upper-left corner of drawing.
PointF drawPoint = new PointF(50 + m, 95);
// Draw string to screen.
g.DrawString(drawString, drawFont, drawBrush, drawPoint);
}
Move your code to the Paint event of the picturebox and use the graphics object from the available arguments.
private void pictureBox1_Paint(object sender, PaintEventArgs e) {
e.Graphics.Clear(Color.White);
if (count == 1)
DrawCar1(e.Graphics);
if (count == 2)
DrawCar2(e.Graphics);
}
public void DrawCar1(Graphics g)
{
g.DrawEllipse(pen1, 50, 125, 30, 30);
g.DrawEllipse(pen1, 150, 125, 30, 30);
// etc.
}
public void DrawCar2(Graphics g)
{
// etc.
}
private void button1_Click(object sender, EventArgs e)
{
count++;
button1.Text = "Move";
pictureBox.Invalidate();
}
Your code never cleared the PictureBox, just the form, but it's a mistake to use CreateGraphics() because that is just a temporary canvas. Any drawing using that method gets wiped out when you minimize the form, for instance.
Your code should probably be refactored into having a "Car" class. Having a Car1 and a Car2 drawing routine isn't very practical. If you want to keep moving it, you don't want to keep adding more Car# routines. Create a single drawing routine for the car and keep the location information in the "Car" class so you know "where" you want the car drawn.