GDI+ Custom Controls with Visual C# 2005
GDI支持的三种绘图界面:
• The Screen. The ability to draw on the screen is arguably the most important feature
when it comes to building custom controls' user interfaces. GDI+ makes it possible
(and easy!) to draw complex shapes, text, and images on screen with great flexibility.
• Images. GDI+ also supports drawing on images, either loaded from a physical
location (like the HDD), or images generated in the memory.
• Printer. Printing is also supported by GDI+, which makes the process very simple
and straightforward.
The Graphics Object
两种方式获取,Control.CreateGraphics(), 或者Paint 事件, which provides the Graphics object as an argument.
Invalidation
After rendering a control, its appearance remains unchanged until the control's surface is
refreshed. The process of refreshing is called invalidation because regions in the control's visible
area become invalid and need to be redrawn. The base class (Control) triggers automatic
invalidation when the control is covered by another window and then is uncovered
基本对象
Point,PointF,Size,SizeF,Rectangle,RectangleF
Drawing Using the Pen Object
方法
Method Description
DrawArc Draws an arc (a section of an ellipse)
DrawBezier Draw a Bezier spline
DrawCurve Draw a cardinal spline through an array of points
DrawEllipse Draw an ellipse
DrawLine Draw a line between 2 points
DrawPolygon Draw a polygon defined by an array of points
最佳实践:主动调用GDI对象的dipose方法
Filling Surfaces Using the Brush Object
SolidBrush Defines a brush that fills paths with a single color.
HatchBrush Defines a brush having a hatch pattern, which can be set from a number of brushes through the HatchStyle property.
LinearGradientBrush Defines a gradient brush. Many gradients types can be achieved with this brush (for example, different angles, and different color weights).
PathGradientBrush Defines a brush that fills a path with a gradient.
TextureBrush Defines a brush that fills a path using an image.
Drawing Text Using the Font Object
可以使用SizeF fontSize = e.Graphics.MeasureString(Text,Font); 得出字体大小
Drawing Complex Shapes and
Using Transformations
The GraphicsPath Object 图形路径对象用于复杂图形
AddArc Appends an arc from an ellipse. It takes as parameters the ellipse dimensions and the angles of the arc.
AddBezier Appends a Bezier line. This method will be explained in an example a bit later.
AddBeziers Appends a series of Bezier lines.
AddClosedCurve Appends a closed curved line between given points based on a tension argument.
AddCurve Appends a curve that is not automatically closed. AddElipse Appends an ellipse that fits inside a rectangle. AddLine Appends a line.
AddLines Appends lines.
AddPath Appends another GraphicsPath.
AddPie Appends a pie slice. AddPolygon Appends a polygonal line. AddRectangle Appends a rectangle.
AddString Appends the path of a given string.
A Region object defines a surface bounded by a path. This surface can be created from a closed
graphics path, or by performing different operations with other regions like union or intersection.
The Region class is tightly related to the GraphicsPath class because most often it is created from
closed GraphicsPath figures. The GraphicsPath is drawn using a Pen object and the Region is
filled using a Brush object.
区域对象,从图形路径创建,用brush填充
区域对象可以进行集合操作
Complement Makes the region contain the portion of the parameter's surface that does not
intersect with it.
Exclude Excludes the parameter's surface from the region.
Intersect Makes the region contain only the surface common to its parameter and itself.
Union Adds to the region the surface of its parameter.
Xor Adds the surface of its parameter and excludes the intersection between the region and the parameter's surface.
Clipping Drawing Using Region Objects
可以达到Keeping Drawing Outside a Region和Keeping Drawing Inside a Region的功能
Graphics Transformations
进行平移,旋转,缩放等操作
例子:Clock Control
Drawing Control Parts, Borders,
and Adornments
Rendering Common Control Parts
ControlPaint类的方法可以重绘各种基本控件
DrawContainerGrabHandle 移动状态
DrawSizeGrip 调整大小状态
Handling Mouse Events
Dragging and Dropping拖拽效果
需要处理的三个事件
o LocationChanged
o MouseDown
o MouseMove
The logic behind the drag-and-drop actions is built into the event
handlers for DragDrop and DragEnter:
private void drawingArea_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop) && count < maxPictures)
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
private void drawingArea_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] fileData = (string[])e.Data.GetData(DataFormats.FileDrop);
try
{
Bitmap bitmap = new Bitmap(fileData[0]);
AddPictureBox(bitmap);
}
catch (Exception ex)
{
MessageBox.Show( "An error has occurred: " + ex.Message,
"Error",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
最后的例子The PieChart Control
foreach (Slice slice in mySlices)
{
Pen penSlice = new Pen(slice.GetSliceColor());
int actualRangeSlice = slice.GetSliceRange();
int startAngle = (int)((actualCount / (double)totalCount) * 360);
int widthAngle = (int)(((actualRangeSlice) / (double)totalCount) * 360) + 1;
That bug occurred because the type-casting from double to integer used to cause some precision loss.
出现了一个bug,GDI绘画的精度问题int和double
特别精度损失问题在图表控件绘制比较常见,要引以为戒