hello how to fill lineargradientbrush on the graphicspath..
i have this code and solidbrush can only fill it.. i dont know how to fill it with lineargradientbrush.. any help please..
i have this code..
class KamoteButton : Button
{
protected override void OnPaint(PaintEventArgs pevent)
{
int width = this.Width-1;
int height = this.Height-1;
Color gradColor_a = Color.FromArgb(162, 177, 183);
Color gradColor_b = Color.FromArgb(104, 111, 114);
int radius = this.Width / 8;
Graphics gFx = pevent.Graphics;
gFx.SmoothingMode = SmoothingMode.AntiAlias;
GraphicsPath gp = new GraphicsPath();
gp.AddArc(0, 0, radius, radius, 180, 90);
gp.AddLine(width / 8, 0, width - width / 8, 0);
gp.AddArc(width - radius, 0, radius, radius, 270, 90);
gp.AddLine(width, width / 8, width, height - width / 8);
gp.AddArc(width - radius, height - radius, radius, radius, 0, 90);
gp.AddLine(width - width / 8, height, width / 8, height);
gp.AddArc(0, height - radius, radius, radius, 90, 90);
gp.AddLine(0, height - width / 8, 0, width / 8);
Rectangle r = new Rectangle(0, 0, 100, 100);
LinearGradientBrush lbg = new LinearGradientBrush(gp, gradColor_a, gradColor_b, LinearGradientMode.Vertical);
SolidBrush sb = new SolidBrush(Color.Red);
gFx.FillPath(lbg, gp);
this.Region = new Region(gp);
}
}
Your code to create the GradientBrushh won't compile:
LinearGradientBrush lbg = new LinearGradientBrush(gp,
gradColor_a, gradColor_b, LinearGradientMode.Vertical);
There is no constructor with a Path as parameter. Replace it with 2 points or 1 Rect
Related
I want to round the corners of the ListView. I can do it on the button so i used the same solution in listview. It seems listview paint event overridden by different methods.
public class RoundListView : ListView
{
private int borderSize = 10;
private int borderRadius = 20;
private Color borderColor = Color.Gray;
private GraphicsPath GetFigurePath(Rectangle rect, float radius)
{
GraphicsPath path = new GraphicsPath();
float curveSize = radius * 2F;
path.StartFigure();
path.AddArc(rect.X, rect.Y, curveSize, curveSize, 180, 90);
path.AddArc(rect.Right - curveSize, rect.Y, curveSize, curveSize, 270, 90);
path.AddArc(rect.Right - curveSize, rect.Bottom - curveSize, curveSize, curveSize, 0, 90);
path.AddArc(rect.X, rect.Bottom - curveSize, curveSize, curveSize, 90, 90);
path.CloseFigure();
return path;
}
protected override void OnPaint(PaintEventArgs pevent)
{
base.OnPaint(pevent);
Rectangle rectSurface = this.ClientRectangle;
Rectangle rectBorder = Rectangle.Inflate(rectSurface, -borderSize, -borderSize);
int smoothSize = 2;
using (GraphicsPath pathSurface = GetFigurePath(rectSurface, borderRadius))
using (GraphicsPath pathBorder = GetFigurePath(rectBorder, borderRadius - borderSize))
using (Pen penSurface = new Pen(this.Parent.BackColor, smoothSize))
using (Pen penBorder = new Pen(borderColor, borderSize))
{
pevent.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
this.Region = new Region(pathSurface);
pevent.Graphics.DrawPath(penSurface, pathSurface);
if (borderSize >= 1)
//Draw control border
pevent.Graphics.DrawPath(penBorder, pathBorder);
}
}
}
I'm using a picturebox to create a visual of an instance of my truss class. I'm creating the visual by drawing directly onto the picture box in the paint event. The method looks like this
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (isDraw)
{
//Preparing to draw
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.Bicubic;
RunEntry entry = this.passedHistory.SelectedItem as RunEntry;
AnsFile objToDraw = entry.FileRead;
Pen pen = new Pen(Color.Black);
//Getting size of bitmap
int maxWidth = 0, maxHeight = 0;
foreach (AnsJoint joint in objToDraw.AnsJoints)
{
if (joint.Location.X.Length > maxWidth)
{
maxWidth = (int)joint.Location.X.Length;
}
if (joint.Location.Y.Length > maxHeight)
{
maxHeight = (int)joint.Location.Y.Length;
}
}
//Drawing joints
foreach (AnsJoint joint in objToDraw.AnsJoints)
{
PointF jointPoint = this.ToCartesian(new PointF((float)joint.Location.X.Length - 4f, (float)joint.Location.Y.Length + 10f), maxHeight);
e.Graphics.DrawString(joint.JointID.ToString(), new Font(FontFamily.GenericMonospace, 6f, FontStyle.Regular, GraphicsUnit.Point, 1, false), Brushes.Black, jointPoint);
}
//Draw the panels and links
foreach (AnsMember member in objToDraw.AnsMembers)
{
List<AnsPanel> panels = member.Panels; //Drawing the panels
foreach (AnsPanel pan in panels)
{
pen.Color = Color.Red;
PointF p1 = this.ToCartesian(new PointF((float)pan.I.Location.X.Length, (float)pan.I.Location.Y.Length), maxHeight);
PointF p2 = this.ToCartesian(new PointF((float)pan.J.Location.X.Length, (float)pan.J.Location.Y.Length), maxHeight);
g.DrawEllipse(pen, p1.X - 2.5f, p1.Y - 2.5f, 5, 5);
g.DrawEllipse(pen, p2.X - 2.5f, p2.Y - 2.5f, 5, 5);
g.DrawEllipse(pen, p1.X - 3, p1.Y - 3.3f, 5, 5);
g.DrawEllipse(pen, p2.X - 3, p2.Y - 3.3f, 5, 5);
pen.Color = Color.Black;
g.DrawLine(pen, p1, p2);
}
List<AnsLink> links = member.Links; //Drawing the links
foreach (AnsLink link in links)
{
PointF p1 = this.ToCartesian(new PointF((float)link.I.Location.X.Length, (float)link.I.Location.Y.Length), maxHeight);
PointF p2 = this.ToCartesian(new PointF((float)link.J.Location.X.Length, (float)link.J.Location.Y.Length), maxHeight);
g.FillEllipse(Brushes.Green, p1.X - 1.5f, p1.Y - 1.5f, 3, 3);
g.FillEllipse(Brushes.Green, p2.X - 1.5f, p2.Y - 1.5f, 3, 3);
g.DrawLine(pen, p1, p2);
}
}
g.ScaleTransform(.5f, .5f);
pictureBox1.Tag = entry.FileName;
}
}
Which yields the result I'm expecting
except that I want the truss image to scale to fill the picturebox more. I added the ScaleTransform call to the end of the paint event method but that doesn't seem to have any impact as the picture is the same size with or without the call. How can I scale what I draw on the picturebox to the size of the picturebox?
Call ScaleTransform before you do your drawing. You can calculate the desired scale factor like this:
// place this code after the calculation of maxWidth and maxHeight
// but before the drawing code
PictureBox p = (PictureBox)sender;
float scaleFactor = Math.Min(
((float)p.Width) / maxWidth,
((float)p.Height) / maxHeight
);
g.ScaleTransform(scaleFactor, scaleFactor);
I want to create a custom combo-box with rounded corners and gradient color. I have implemented the same feature in Button by overriding the OnPaint method. But it is not working for ComboBox. Any help will be appreciated.
The code I am using for overriding OnPaint is given below:
protected override void OnPaint(PaintEventArgs paintEvent)
{
Graphics graphics = paintEvent.Graphics;
SolidBrush backgroundBrush = new SolidBrush(this.BackColor);
graphics.FillRectangle(backgroundBrush, ClientRectangle);
graphics.SmoothingMode = SmoothingMode.AntiAlias;
Rectangle rectangle = new Rectangle(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - 1, ClientRectangle.Height - 1);
GraphicsPath graphicsPath = RoundedRectangle(rectangle, cornerRadius, 0);
Brush brush = new LinearGradientBrush(rectangle, gradientTop, gradientBottom, LinearGradientMode.Horizontal);
graphics.FillPath(brush, graphicsPath);
rectangle = new Rectangle(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - 1, ClientRectangle.Height - 100);
graphicsPath = RoundedRectangle(rectangle, cornerRadius, 2);
brush = new LinearGradientBrush(rectangle, gradientTop, gradientBottom, LinearGradientMode.Horizontal);
graphics.FillPath(brush, graphicsPath);
}
private GraphicsPath RoundedRectangle(Rectangle rectangle, int cornerRadius, int margin)
{
GraphicsPath roundedRectangle = new GraphicsPath();
roundedRectangle.AddArc(rectangle.X + margin, rectangle.Y + margin, cornerRadius * 2, cornerRadius * 2, 180, 90);
roundedRectangle.AddArc(rectangle.X + rectangle.Width - margin - cornerRadius * 2, rectangle.Y + margin, cornerRadius * 2, cornerRadius * 2, 270, 90);
roundedRectangle.AddArc(rectangle.X + rectangle.Width - margin - cornerRadius * 2, rectangle.Y + rectangle.Height - margin - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90);
roundedRectangle.AddArc(rectangle.X + margin, rectangle.Y + rectangle.Height - margin - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90);
roundedRectangle.CloseFigure();
return roundedRectangle;
}
I was able to find a solution to this problem. Actually, the problem was that OnPaint event was not getting called for Combobox. So I had to do the following changes.
public CustomComboBox()
{
InitializeComponent();
SetStyle(ControlStyles.UserPaint, true);
}
I had to call SetStyle() method inside the constructor so that OnPaint() event will get called.
I found this post as helful : OnPaint override is never called
The same solution can be used for Custom TextBoxes.
I need to be able to rotate text in a label and align it to the left, right or center. So far I am able to do rotation with this code in the derived label's onPaint method:
float width = graphics.MeasureString(Text, this.Font).Width;
float height = graphics.MeasureString(Text, this.Font).Height;
double angle = (_rotationAngle / 180) * Math.PI;
graphics.TranslateTransform(
(ClientRectangle.Width + (float)(height * Math.Sin(angle)) - (float)(width * Math.Cos(angle))) / 2,
(ClientRectangle.Height - (float)(height * Math.Cos(angle)) - (float)(width * Math.Sin(angle))) / 2);
graphics.RotateTransform(270f);
graphics.DrawString(Text, this.Font, textBrush, new PointF(0,0), stringFormat);
graphics.ResetTransform();
And it works fine. I can see text rotated 270 degrees.
But when I try to set alignment in stringFormat it goes crazy, and I can't figure out what's going on.
How can I have text rotated by 270 degrees and align it to up?
In case somebody was looking for tips, here is the solution for 0, 90, 180, 270, and 360 degrees rotation, where StringAligment works.
One thing was choosing the right point for moving the origin to, and the second one was to modify the display rectangle according to rotation.
StringFormat format = new StringFormat();
format.Alignment = StringAlignment.Center;
SizeF txt = e.Graphics.MeasureString(Text, this.Font);
SizeF sz = e.Graphics.VisibleClipBounds.Size;
//90 degrees
e.Graphics.TranslateTransform(sz.Width, 0);
e.Graphics.RotateTransform(90);
e.Graphics.DrawString(Text, this.Font, Brushes.Black, new RectangleF(0, 0, sz.Height, sz.Width), format);
e.Graphics.ResetTransform();
//180 degrees
e.Graphics.TranslateTransform(sz.Width, sz.Height);
e.Graphics.RotateTransform(180);
e.Graphics.DrawString(Text, this.Font, Brushes.Black, new RectangleF(0, 0, sz.Width, sz.Height), format);
e.Graphics.ResetTransform();
//270 degrees
e.Graphics.TranslateTransform(0, sz.Height);
e.Graphics.RotateTransform(270);
e.Graphics.DrawString(Text, this.Font, Brushes.Black, new RectangleF(0, 0, sz.Height, sz.Width), format);
e.Graphics.ResetTransform();
//0 = 360 degrees
e.Graphics.TranslateTransform(0, 0);
e.Graphics.RotateTransform(0);
e.Graphics.DrawString(Text, this.Font, Brushes.Black, new RectangleF(0, 0, sz.Width, sz.Height), format);
e.Graphics.ResetTransform();
If you put this code in label's OnPaint event, it would display your rotated form's title four times.
Extension of Adrian Serafin's answer if you need to draw at a non-0 X,Y:
//90 degrees
e.Graphics.TranslateTransform(sz.Width, 0);
e.Graphics.RotateTransform(90);
e.Graphics.DrawString(Text, this.Font, Brushes.Black,
new RectangleF(sz.ToPointF().Y, sz.ToPointF().X, sz.Height, sz.Width), format);
e.Graphics.ResetTransform();
//180 degrees
e.Graphics.TranslateTransform(sz.Width, sz.Height);
e.Graphics.RotateTransform(180 this.Font, Brushes.Black,
new RectangleF(-sz.ToPointF().X, -sz.ToPointF().Y, sz.Width, sz.Height), format);
e.Graphics.ResetTransform();
//270 degrees
e.Graphics.TranslateTransform(0, sz.Height);
e.Graphics.RotateTransform(270);
e.Graphics.DrawString(Text, this.Font, Brushes.Black,
new RectangleF(-sz.ToPointF().Y, sz.ToPointF().X, sz.Height, sz.Width), format);
//0 = 360 degrees
e.Graphics.TranslateTransform(0, 0);
e.Graphics.RotateTransform(0);
e.Graphics.DrawString(Text, this.Font, Brushes.Black,
new RectangleF(sz.ToPointF().X, sz.ToPointF().Y, sz.Width, sz.Height), format);
e.Graphics.ResetTransform();
I am using the code below to change to shape of the winform.
It's changing the shape, but not like how I wanted.
I need the form to have curved corners.
What points should I use to get it?
public void MakeNonRectangularForm()
{
var p = new GraphicsPath();
int width = ClientSize.Width;
int height = ClientSize.Height;
p.AddClosedCurve(new Point[] { new Point(width / 2, height / 2),
new Point(width, 0), new Point(width, height / 3),
new Point(width - width / 3, height),
new Point(width / 7, height - height / 8)});
Region = new Region(p);
}
The following is some code I have used to create rounded edges before, using AddArc and lines to piece together the border:
(You can play with xRadius and yRadius to achieve your desired amount of "rounded-ness")
int xRadius = {insert value here};
int yRadius = {insert value here};
GraphicsPath edge = new GraphicsPath();
int rightHandLeft = this.Width - xRadius - 1;
int bottomSideTop = this.Height - yRadius - 1;
edge.AddArc(0, 0, xRadius, yRadius, 180, 90);
edge.AddLine(xRadius, 0, rightHandLeft, 0);
edge.AddArc(rightHandLeft, 0, xRadius, yRadius, 270, 90);
edge.AddLine(this.Width, yRadius, this.Width, bottomSideTop);
edge.AddArc(rightHandLeft, bottomSideTop, xRadius, yRadius, 0, 90);
edge.AddLine(rightHandLeft, this.Height, xRadius, this.Height);
edge.AddArc(0, bottomSideTop, xRadius, yRadius, 90, 90);
edge.AddLine(0, bottomSideTop, 0, yRadius);
this.Region = new Region(edge);