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?
Related
For reasons of aesthetics, I want to create a line composed of parallelograms like this:
But it turns out that the OnPaint override event only allows you to draw rectangles:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Rectangle[] rectangles = new Rectangle[]
{
new Rectangle(0, 0, 100, 30),
new Rectangle(100, 0, 100, 30),
new Rectangle(200, 0, 100, 30),
new Rectangle(300, 0, 100, 30),
new Rectangle(400, 0, 100, 30),
};
e.Graphics.DrawRectangles(new Pen(Brushes.Black), rectangles);
}
My problem is that I need to convert the rectangles into parallelograms, and give each one a different color.
The FillPolygon can do the job:
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
e.Graphics.Clear(Color.White);
int x = 10;
int y = 10;
int width = 148;
int height = 64;
int lean = 36;
Color[] colors = new[] { Color.FromArgb(169, 198, 254),
Color.FromArgb(226, 112, 112),
Color.FromArgb(255, 226, 112),
Color.FromArgb(112, 226, 112),
Color.FromArgb(165, 142, 170)};
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
for (int i = 0; i < colors.Length; ++i) {
using (SolidBrush br = new SolidBrush(colors[i])) {
e.Graphics.FillPolygon(br, new Point[] { new Point(x, y),
new Point(x + lean, y + height),
new Point(x + lean + width, y + height),
new Point(x + width, y)});
x += width;
}
}
}
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 have several outputs for my datas and want to create one fill-Object for any output-possibility. For example PrintDocument and Bitmap. Thats works with Graphics-Object, but the result is different.
My test method for fill graphics:
protected void fillGraphics(Graphics g)
{
g.PageUnit = GraphicsUnit.Pixel;
Pen pen = new Pen(Brushes.Black, 3);
g.DrawRectangle(pen, 100, 100, 300, 300);
g.DrawString("Wichtig!", new System.Drawing.Font(FontFamily.GenericSansSerif, 16), new SolidBrush(Color.Black), 120, 120);
}
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);
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();
}