|
|
Creating Controls
Lesson 1 GDI+
-
GCI+ = .net managed implementation of GDI
System.Drawing Namespace
-
Summary
-
System.Drawing most of classes actually involved with rendering to screen
-
System.Drawing.Design extend design time UI
-
System.Drawing.2D advanced visual effects
-
System.Drawing.Imaging manipulation of image files
-
System.Drawing.Printing print support
-
System.Drawing.Text font manipulation
System.Drawing.Graphics Object
-
Principle object in rendering graphics
-
Represents drawing surface of visual element, e.g. form, control, Image, etc.
-
Can not directly instantiate call CreateGraphics method on class deriving
from Control
-
When working with Image can obtain from static Graphics.FromImage method
System.Drawing.Graphics
myFormGraphics;
myFormGraphics =
myForm.CreateGraphics();
Bitmap myImage = new
Bitmap(C:\\myImage.bmp);
System.Drawing.Graphics
myBmpGraphics;
myBmpGraphics =
Graphics.FromImage(myImage);
Coordinates
-
Rendering occurs in region set by control bounds
-
Origin = upper left hand corner
-
Measured in screen pixels
-
Variety of structures describe location in region
-
Point single point with int values for X and Y
-
PointF single point with float values for X and Y
-
Size rectangular size consisting of paired height and width values as
integers
-
SizeF - rectangular size consisting of paired height and width values as float
-
Rectangle top, bottom, left and right edges specified by int values
-
RectangleF top, bottom, left and right edges specified by float values
-
Integral locations can be implicitly converted to floating-point counterparts
-
To convert floating-point to integer locations must explicitly convert each
point
-
Note size structure indicate size, but not position
-
Create rectangle by supplying Size and Point (upper left hand corner)
Point myOrigin = new
Point(10,10);
Size mySize = new
Size(20,20);
Rectangle myRectangle = new
Rectangle(myOrigin, mySize);
Drawing Shapes
-
Graphics object contains many methods to render shapes on screen
-
Those beginning Draw, e.g. DrawArc, DrawPie, draw line structures, outlines,
etc.
-
Those beginning Fill, e.g. FillRegion, FillRectangle, render solid shapes
-
Methods take parms specifying coordinates and location of shape to draw. Also
require object to perform rendering a Pen for Draw
and Brush for Fill
Colors, Brushes, Pens
-
System.Drawing.Color represent single color. Specified by 4 values alpha
which specifies transparency and Red, Green and blue values. Each value in
range 0 to 255
-
Can also specify named colours, e.g. Color.Tomato
-
All brushes derive from abstract Brush class
-
System.Drawing.SolidBrush single solid colour
-
System.Drawing.TextureBrush fills object with an image
-
System.Drawing.Drawing2D.HatchBrush fills with hatch pattern
-
System.Drawing.Drawing2D.LinearGradientBrush blends 2 colours along a
gradient
-
System.Drawing.Drawing2D.PathGradientBrush render complex gradient
-
Only one Pen class and it cannot be inherited. When create specify colour and
width
-
Use SystemColors, SystemPens and SystemBrushes class to ensure UI has same look
and feel as rest of system, e.g. Highlight text colour available from
System.Colors.HighlightText
Rendering
-
Always Dispose of graphics objects when finished use a lot of resources,
failure to do so -> application degredation
SolidBrush myBrush = new
SolidBrush(Color.MintCream);
Graphics g =
this.CreateGraphics();
Rectangle myRectangle = new
Rectangle(0, 0, 30, 20);
g.FillElipse(myBrush,
myRectangle);
g.Dispose();
myBrush.Dispose();
-
To render text
-
Create Font and Brush objects
-
Obtain reference to Graphics object
-
Call Graphics.DrawString specifying string, font, brush and location
-
Dispose of objects
-
Complex Shapes
-
Obtain reference to Graphics object
-
Create instance of GraphicsPath class
-
Add figures to GraphicsPath
-
Call Graphics.DrawPath to draw path outline or Graphics.FillPath to fill shape
-
Dispaose of Graphics object
-
The GraphicsPath object describes any complex closed shape or set of shapes
GraphicsPath myPath = new
GraphicsPath(new Point[] {new Point(1,1), new Point(32,54), new
Point(33,5)}, new byte[] {(byte)PathPointType.Start,
(byte)PathPointType.Line, (byte)PathPoint.Bezier});
-
Add figures to path using methods such as
-
GraphicsPath.AddClosedCurve
-
GraphicsPath.AddElipse
-
GraphicsPath.AddPie
-
GraphicsPath.AddString
-
-
Can create figures by adding lines, arcs, curves, etc.
-
Begin by calling GraphicsPath.StartFigure
-
Add lines
-
Optionally call GraphicsPath.CloseFigure (if not called figure is closed at run
time by drawing line from first point to last)
Lesson 2 Authoring Controls
Inheritance
-
All controls inherit (directly or indirectly) from Control class
-
Provides low level logic for UI and common control methods
-
No code to render control
-
No code to provide unique functionality
-
Inherit from existing control = easiest way create new control
-
Inherits functionality and appearance
-
Can inherit from most Windows Forms controls (other than those marked sealed)
-
Use if retaining look and functionality of existing control but with some
custom additions
-
Use if wish to retain functionality of existing control but a new look
-
Do not use if need radically different functionality
-
Inherit from UserControl
-
Single control may not provide all functionality required, e.g. want control
bound to data source that shows first name, last name and phone number in
separate TextBox
-
Rather than implement logic in form can group multiple Windows Form controls
into single unit (User Control)
-
Sometimes called Composite Control
-
UserControl provides base functionality
-
UserControl designer allows other Windows Form controls to be added and custom
functionality implemented
-
Limited customisation of UI just configuring ands positioning constituent
controls
-
Use when need to combine functionality of multiple existing controls and
additional logic as single unit
-
Inherit from Control
-
Create custom control if rich UI or functionality unachievable via other
inheritance mencahisms
-
Must program logic specific to control and code required to render visual
representation
-
Additional members
-
Add to control in same way as add to class (at any access level)
-
Form hosting control has access to public members
-
Public properties are automatically displayed in Properties window (unless
Browsable attribute is false)
[System.ComponentModel.Browsable(false)]
public int
StockNumber
{
}
Create Inherited Control
-
Can either add new functionality or override members exposed by base class
public class NumberBox :
System.Windows.Forms.TextBox
{
protected
override void
OnKeyPress(KeyPressEventArgs
e)
{
if(char.IsNumber(e.KeyChar) == false)
e.Handled = true;
}
}
-
Override OnPaint method to modify control appearance, e.g to create button
rendered as string of text
public class Wowbutton :
System.Windows.Forms.Button
{
protected
override void
OnPaint(PaintEventArgs
pe)
{
System.Drawing.Drawing2D.GraphicsPath myPath = new
System.Drawing.Drawing2D.GraphicsPath();
myPath.AddString(Wow!, Font.Family, (int)Font.Style, 72, new
PointF(0,0), StringFormat.GenericDefault);
Region myRegion = new Region(myPath);
this.Region = myRegion;
}
}
-
Note some controls, e.g. TextBox, drawn by form they exist on and not by the
control itself, thus Paint() never called.
Creating UserControl
-
Create class derived from UserControl
-
Add Windows Form controls via UserControl designer
-
Expose any appropriate properties from constituent controls
-
Write custom functionality for user control
-
Constituent controls are treated as private
-
If want to allow other developers to change properties of constituent controls
must selectively expose them through properties of the user control
public color
ButtonColor
{
get
{
return Button1.BackColor;
}
set
{
Button1.BackColor = value;
}
}
-
Can expose entire constituent control by changing Modifiers property to desired
access level. Property only available in Properties window does not exist at
runtime.
Creating Custom Control
-
Most customisable and configurable, but most time consuming to develop
-
Must write all code to render visual representation most time-intensive part
of control development
-
Default handler for Paint event is OnPaint() method
-
Coordinates measured relative to upper left corner of control
protected override void
OnPaint(PaintEventArgs e)
{
Brush aBrush =
new SolidBrush(Color.Red);
Rectangle
clientRectangle = new Rectangle(new
Point(0,0),
this.Size);
e.Graphics.FillEllipse(aBrush,
clientRectangle);
}
-
When control resized ClipRectangle resized but control not necessarily redrawn.
Can force redraw by using Control.SetStyle to set ResizeRedraw flag to true
-
Can manually cause redraw by calling Refesh method
Lesson 3 Using Controls
Adding to Toolbox
-
Right click toolbox, choose Customize
-
Choose .NET Framework Components Tab and click Browse
-
Select DLL or EXE containing control
-
Control is added to toolbox
Providing Toolbox Bitmap
-
VisualStudio provide default icon bitmap for custom controls in toolbox
-
Specify custom bitmap viaToolboxBitmapAttribute class
-
Specify 16 by 16 pixel bitmap to use or
[ToolboxBitmap(@C:\Pasta.bmp)
public class PastaMaker :
Control
{
}
-
Specify a type custom control will have same Toolbox bitmap as that of
specified type
[ToolboxBitmpa(typeof(Button))]
public class myButton :
Button
{
}
Debugging Control
-
Controls are not stand-alone projects must be hosted within Windows Form
project while debugging
-
If control part of executable project add new Windows Form to project to hold
control
-
If control part of non-executable project (e.g. class library) add additional
project to solution to test control
Licensing
-
.NET provides built-in license management
-
Default licensing model requires any control to be licensed to have
LicenseProviderAttribute applied to it
-
Specifies LicenseProvider to use for validating license
-
LicenseProvider = abstract class providing standard interface for validation
-
In control constructor call LicenseManager.Validate to return reference to
valid license if control not licensed it will fail to load
-
LicenseManager.Validate validates license by calling LicenseProvider.GetLicense
retrieves license and checks validity by calling LicenseProvider.IsKeyvalid
-
Validation scheme depends on LicenseProvider implementation
-
.NET Framework includes implementation of LicesneProvider called
LicFileLicenseProvider
-
GetLicense method of LicFileLicenseProvider searches for text file named
<FullName>.LIC (where FullName = fully qualified control name)
-
Can override to provide own validation logic
-
Implement dispose for every licensed control
[LicenseProvider(typeof(LicFileLicenseProvider))]
public class Widget :
System.Windows.Forms.Control
{
private License myLicense;
public Widget()
{
myLicense =
LicenseManager.Validate(typeof(Widget),
this);
}
protected override void Dispose(bool
Disposing)
{
if(myLicense != null)
{
myLicense.Dispose();
myLicense = null;
}
}
}
Hosting in IE
-
Every Windows Forms control can be hosted within IE
-
To host in IE, control must be installed in
-
Global Assembly cache
-
same virtual directory as HTML page it is declared in
-
Add to HTML page via <OBJECT> tag which specifies controls classid
-
Classid = 2 parts
-
Path to file containing control
-
Fully qualified name of control
<OBJECT id=myControl
classid=http:ControlLibrary.dll#ControlLibrary1.myControl
VIEWASTEXT>
</OBJECT>
|
|