- •Table of Contents
- •C# and the .NET Platform, Second Edition
- •Introduction
- •Part One: Introducing C# and the .NET Platform
- •Part Two: The C# Programming Language
- •Part Three: Programming with .NET Assemblies
- •Part Four: Leveraging the .NET Libraries
- •Part Five: Web Applications and XML Web Services
- •Obtaining This Book's Source Code
- •The .NET Solution
- •What C# Brings to the Table
- •The Role of the Assembly Manifest
- •Summary
- •Chapter 2: Building C# Applications
- •Summary
- •Chapter 3: C# Language Fundamentals
- •Defining Program Constants
- •Defining Custom Class Methods
- •C# Enumerations
- •Summary
- •The Second Pillar: C#'s Inheritance Support
- •Summary
- •Catching Exceptions
- •Finalizing a Type
- •Garbage Collection Optimizations
- •Summary
- •Chapter 6: Interfaces and Collections
- •Building Comparable Objects (IComparable)
- •Summary
- •Summary
- •Internal Representation of Type Indexers
- •Summary
- •An Overview of .NET Assemblies
- •Understanding Delayed Signing
- •Using a Shared Assembly
- •GAC Internals
- •Summary
- •Spawning Secondary Threads
- •A More Elaborate Threading Example
- •Summary
- •Summary
- •Object Persistence in the .NET Framework
- •The .NET Remoting Namespaces
- •Understanding the .NET Remoting Framework
- •All Together Now!
- •Terms of the .NET Remoting Trade
- •Testing the Remoting Application
- •Revisiting the Activation Mode of WKO Types
- •Deploying the Server to a Remote Machine
- •Summary
- •Control Events
- •The Form Class
- •Summary
- •Regarding the Disposal of System.Drawing Types
- •Understanding the Graphics Class
- •Summary
- •The TextBox Control
- •Working with Panel Controls
- •Configuring a Control's Anchoring Behavior
- •Summary
- •Chapter 16: The System.IO Namespace
- •The Static Members of the Directory Class
- •The Abstract Stream Class
- •Summary
- •The Role of ADO.NET Data Providers
- •The Types of System.Data
- •Selecting a Data Provider
- •The Types of the System.Data.OleDb Namespace
- •Working with the OleDbDataReader
- •Summary
- •Submitting the Form Data (GET and POST)
- •Some Benefits of ASP.NET
- •Creating an ASP.NET Web Application by Hand
- •The Composition of an ASP.NET Page
- •The Derivation of an ASP.NET Page
Regarding the Disposal of System.Drawing Types |
|
C# and the .NET P atform, Second Edition |
|
by Andrew Troelsen |
ISBN:1590590554 |
Before diving intoAprspecificss GDI+ topics, it is important to point out that a number of types within the
© 2003 (1200 pages)
System.Drawing.dll assembly implement the IDisposable interface. As you recall from Chapter 5, this
This comprehensive text starts with a brief overview of the
interface definesC#a singlelanguagemethodand namedthen quicklyDispose(),moves whichto keymaytechnicalbe calledand by the object user to release any internally managedarchitecturalresourcesissuesof thefortype.NET. developers.
When you make use of GDI+, your best bet is to explicitly call Dispose() on any type you have explicitly
Tablecreatedof Contentsvia the C# "new" keyword (when you are finished interacting with it) to ensure that the type cleans C#upandanytheinternally.NET Plallocatedtf rm, SecondmemoryEditionas soon as possible. On the other hand, when operating on a GDI+
type passed as a member parameter or received via a method invocation, you should not call Dispose(),
Introduction
because another part of the system may still require the type. To illustrate:
Part One - Introducing C# and the .NET Platform
Chapter 1 - The Philosophy of .NET
Chapterprivate2 -voiBu ldingmainFormC# ApplicationsPaint(object sender, PaintEventArgs e)
Part{ Two - The C# Programming Language
Chapter//3 Get- C# LanguageGraphicsFundamentalsobject from param (don't dispose!).
Graphics g = e.Graphics;
Chapter 4 - Object-Oriented Programming with C#
// Make a SolidBrush (you new-ed it, dispose when done)
Chapter 5 - Exceptions and Object Lifetime
SolidBrush br = new SolidBrush(...);
Chapter 6 - Interfaces and Collections
br.Dispose();
Chapter 7 - Callback Interfaces, Delegates, and Events
}
Chapter 8 - Advanced C# Type Construction Techniques
Part Three - Programming with .NET Assemblies
Chapter 9 - Understanding .NET Assemblies
Recall, however, that if you fail (or forget) to call Dispose() on an IDisposable compatible type, the
Chapter 10 - Processes, AppDomains, Contexts, and Threads
garbage collector will eventually clean up the allocated memory. The only downfall to this lazy approach is
Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming
the fact that you do not know exactly when the .NET garbage collector will kick in. If your application
Part Four - Leveraging the .NET Libraries
happens to be installed on a machine with large amounts of memory, the lazy approach may be just fine.
Chapter 12 - Object Serialization and the .NET Remoting Layer
However, as you can never be completely sure about the hardware of the hosting machine, it is best to
Chapterdispose13of-allBuildingGDI+ objectsa B tteryouWindowcreate(IntroducingASAP. Windows Forms)
Chapter 14 - A Better Painting Framework (GDI+)
Note For simplicity, I will abide by the lazy approach in this chapter and will not directly call Dispose()
Chapter 15 - Programming with Windows Forms Controls
on the types created in this chapter's example applications.
Chapter 16 - The System.IO Namespace
Chapter 17 - Data Access with ADO.NET
Part Five - Web Applications and XML Web Services
Chapter 18 - ASP.NET Web Pages and Web Controls
Chapter 19 - ASP.NET Web Applications
Chapter 20 - XML Web Services
Index
List of Figures
List of Tables
UnderstandingC# andPaintthe .NETSessionsPlatform, Second Edition
by Andrew Troelsen |
ISBN:1590590554 |
As you have seen in the previous chapter, the Control class defines a virtual method named OnPaint(). When
Apress © 2003 (1200 pages)
a Form (or any descendent of Control) wishes to render graphical information, you may override this method
This comprehensive text starts with a brief overview of the and extract a GraphicsC# languageobjectandfromthenthequicklyincomingmovesPaintEventArgsto k y technicparameter:l nd
architectural issues for .NET developers.
public class MainForm : Form
{
Table of Contents
public MainForm()
C# and the .NET Platform, Second Edition
{
Introduction
CenterToScreen();
Part One - Introducing C# and the .NET Platform
this.Text = "Basic Paint Form";
Chapter 1 - The Philosophy of .NET
}
Chapter 2 - Building C# Applications
public static void Main(string[] args)
Part Two{- The C# Programming Language
Chapter 3 - C# Language Fundamentals
Application.Run(new MainForm());
Chapter 4 - Object-Oriented Programming with C#
}
Chapter protected5 - Ex eptionsoverrideand Obj ctvoidLifetimeOnPaint(PaintEventArgs e)
Chapter {6 - Interfaces and Collections
Chapter 7 - CallbGraphicsck Interfaces,g = Delegates,.Graphicsand;Events
g.DrawString("Hello GDI+", new Font("Times New Roman", 20),
Chapter 8 - Advanced C# Type Construction Techniques
new SolidBrush(Color.Black), 0, 0);
Part Three - Programming with .NET Assemblies
// If overriding OnPaint(), be sure to call base class implementation.
Chapter 9 - Understanding .NET Assemblies
base.OnPaint(e);
Chapter 10 - Processes, AppDomains, Contexts, and Threads
}
Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming
}
Part Four - Leveraging the .NET Libraries
Chapter 12 - Object Serialization and the .NET Remoting Layer
Chapter 13 - Building a Better Window (Introducing Windows Forms)
Recall that when responding to GUI-based events, you actually have two options at your disposal. In the
Chapter 14 - A Better Painting Framework (GDI+)
previous code you overrode the OnPaint() method directly. The other approach is to directly handle the raw
Chapter 15 - Programming with Windows Forms Controls
Paint event using the associated PainEventHandler delegate:
Chapter 16 - The System.IO Namespace
Chapter 17 - Data Access with ADO.NET public class MainForm : Form
Part Five - Web Applications and XML Web Services
{
Chapter 18 - ASP.NET Web Pages and Web Controls |
|
public MainForm() |
|
Chapter 19 - ASP.NET Web Applications |
|
{ |
|
Chapter 20 - XML Web Services |
|
|
// The VS .NET Property Window would rig this |
Index |
// up in InitializeComponent() |
|
|
List of Figures |
this.Paint += new |
List of Tables |
System.Windows.Forms.PaintEventHandler(MainForm_Paint); |
} |
|
// Note the signature of the event handler...
public void MainForm_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
...
}
...
}
Regardless of how you respond to the Paint event, be aware that whenever a window becomes "dirty" a paint message is placed into the application's message queue. As you are most likely aware, a window is "dirty" whenever it is resized, covered by another window (partially or completely) or is minimized and then restored. Eventually, the flow of logic is routed to the method that handles repainting the window. In these cases, the
.NET Framework ensures that when your Form needs to be redrawn, the Paint handler is called automatically.
C# and the .NET Platform, Second Edition
by Andrew Troelsen |
ISBN:1590590554 |
Invalidating Your© 2003Client(1200 pages)Area |
|
Apress |
|
This comprehensive text starts with a brief overview of the
During the flow of your GDI+ application, you may need to explicitly inform a window that it needs to redraw
C# language and then quickly moves to key technical and
itself (in other words, you need to place a paint message into the queue programmatically). For example, you architectural issues for .NET developers.
may have a program that allows the user to select from a number of bitmap images using a custom dialog. Once the dialog is dismissed, you need to draw the newly selected image onto the client area. Obviously, if Tableyou waitedof Contentsfor the window to become "naturally dirty," the user would not see the change take place until it
was resized or covered by another window. When you need to force a window to repaint itself
C# and the .NET Platform, Second Edition
programmatically, call Invalidate(). For example:
Introduction
Part One - Introducing C# and the .NET Platform
Chapterpublic1 class- The PhilosophyMainForm:of .NETForm
Chapter{ 2 - Building C# Applications
Part...Two - The C# Programming Language
private void MainForm_Paint(object sender, PaintEventArgs e)
Chapter 3 - C# Language Fundamentals
{
Chapter 4 - Object-Oriented Programming with C#
Graphics g = e.Graphics;
Chapter 5 - Exceptions and Object Lifetime
// Assume logic to render a bitmap...
Chapter 6 - Interfaces and Collections
}
Chapter 7 - Callback Interfaces, Delegates, and Events
private void GetNewBitmap()
Chapter 8 - Advanced C# Type Construction Techniques
{
Part Three - Programming with .NET Assemblies
// Show dialog and get new image...
Chapter 9 - Understanding .NET Assemblies
// Repaint the client area.
Chapter 10 - Processes, AppDomains, Contexts, and Threads
Invalidate();
Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming
}
Part Four - Leveraging the .NET Libraries
}
Chapter 12 - Object Serialization and the .NET Remoting Layer Chapter 13 - Building a Better Window (Introducing Windows Forms)
ChapterDo be aware14 - AthatBetterthePaintingInvalidate()Frameworkmethod(GDI+)has been overloaded a number of times to allow you to specify a Chapterspecific15rectangular- Programmingregionwithto repaint,WindowsratherFormsthanContherolsentire client area (which is the default). If you only wish to
update the extreme upper left rectangle of the client area, you could write:
Chapter 16 - The System.IO Nam space
Chapter 17 - Data Access with ADO.NET
Part// FiveRepaint- Web Applicatiogivensrectangularand XML Web Servicesarea of the Form.
Chapterprivate18 -voidASP.NETUpdateUpperArea()Web Pages and Web Controls
Chapter{ 19 - ASP.NET Web Applications
Rectangle myRect = new Rectangle(0, 0, 75, 150);
Chapter 20 - XML Web Services
Index Invalidate(myRect);
}
List of Figures
List of Tables
Obtaining a Graphics Type Outside a Paint Handler
On a related note, you may find yourself in the position of needing to render some image outside the scope of a standard Paint event handler. For example, assume you wish to draw a small circle at the (x,y) position where the mouse has been clicked. The first step (of course) is to locate a valid Graphics object, which can be obtained using the static Graphics.FromHwnd() method. Notice that you are passing your current Handle as the sole parameter (recall that the Handle property is inherited from the Control class):
private void MainForm_MouseDown(object sender, MouseEventArgs e)
{
// Grab a Graphics object via Hwnd.
Graphics g = Graphics.FromHwnd(this.Handle);
// Now draw a 10*10 circle at mouse click.
g.DrawEllipse(new Pen(Color.Green), e.X, e.Y, 10, 10);
}
C# and the .NET Platform, Second Edition
by Andrew Troelsen |
ISBN:1590590554 |
While this logic rendersApr ss ©a2003circle(1200outsidepages)an OnPaint() event handler, it is very important to understand that if the form is invalidatedThis(andcomprehthus redrawn),nsive texteachstartsofwiththe circlesa brief areoverviewerased!of theThis should make sense, given that this rendering only happensC# languagewithinandthethencontextquicklyof amouseoves toclickkey.technical and
architectural issues for .NET developers.
A better approach is to have the MouseUp logic add a new point to an internal collection (such as an ArrayList) of Point objects, followed by a call to Invalidate(). At this point, the OnPaint() method can simply iterate over
Table of Contents
the collection and draw each item:
C# and the .NET Platform, Second Edition
Introduction
public class MainForm : System.Windows.Forms.Form
Part One - Introducing C# and the .NET Platform
{
Chapter 1 - The Philosophy of .NET
// Used to hold all the points.
Chapter 2 - Building C# Applications
private ArrayList myPts = new ArrayList();
Part Two - The C# Programming Language
...
Chapter 3 - C# Language Fundamentals
private void MainForm_MouseDown(object sender, MouseEventArgs e)
Chapter {4 - Object-Oriented Programming with C#
Chapter 5 - Exceptions// Add andto ObjectpointsLifetimecollection.
Chapter 6 - InterfacesmyPts.andAdd(newCollectionsPoint(e.X, e.Y));
Invalidate();
Chapter 7 - Callback Interfaces, Delegates, and Events
}
Chapter 8 - Advanced C# Type Construction Techniques
private void MainForm_Paint(object sender, PaintEventArgs e)
Part Three - Programming with .NET Assemblies
{
Chapter 9 - Understanding .NET Assemblies
Graphics g = e.Graphics;
Chapter 10 - Processes, AppDomains, Contexts, and Threads
g.DrawString("Hello GDI+", new Font("Times New Roman", 20),
Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming
new SolidBrush(Color.Black), 0, 0);
Part Four - Leveraging the .NET Libraries
// Draw all points in ArrayList.
Chapter 12 - Object Serialization and the .NET Remoting Layer foreach(Point p in myPts)
Chapter 13 - Building a Better Window (Introducing Windows Forms)
g.DrawEllipse(new Pen(Color.Green), p.X, p.Y, 10, 10);
Chapter 14 - A Better Painting Framework (GDI+)
}
Chapter 15 - Programming with Windows Forms Controls
}
Chapter 16 - The System.IO Namespace Chapter 17 - Data Access with ADO.NET
Part Five - Web Applications and XML Web Services
Obtaining a Graphics Type from Windows Forms Controls
Chapter 18 - ASP.NET Web Pages and Web Controls
Chapter 19 - ASP.NET Web Applications
As you have seen, the Graphics.FromHwnd() method provides a handy way to obtain a Graphics object for a
Chapter 20 - XML Web Services
Form outside a registered paint handler. However, this same method can also be used to extract a Graphics
Index
type from any System.Windows.Forms.Control-derived type. For example, assume you have two Button types
List of Figures
on a single Form. The first button (named btnRenderToOtherButton) has the following Click event handler:
List of Tables
private void btnRenderToOtherButton_Click(object sender, System.EventArgs e)
{
// Get graphics object for Button on Form.
Graphics buttonGraphics =
Graphics.FromHwnd(btnRenderedButton.Handle);
//Make an interesting brush.
//(must 'use' System.Drawing.Drawing2D namespace to get HatchBrush!)
HatchBrush b = new HatchBrush(HatchStyle.Cross,
Color.Purple, Color.Gold);
// Render brush patter on the left side of button.
buttonGraphics.FillRectangle(b, 0, 0, 50, btnRenderedButton.Height);
}
When you click this button, the appearance of the other button (named btnRenderedButton) is updated with a
custom rectangular region established using a System.Drawing.Drawing2D.HatchBrush type (more on brush
C# and the .NET Platform, Second Edition
types later in this chapter). Figure 14-1 shows a test run of this initial GDI+ application.
by Andrew Troelsen |
ISBN:1590590554 |
Apress © 2003 (1200 pages)
brief overview of the
key technical and
.
Table
C# and
Part
Chapter
Chapter
Part
Chapter
Chapter
Chapter
Chapter
Chapter
Chapter
Part ThreeFigure- Programming14-1: A simplewithGDI+.NETapplicationAssemblies
Chapter 9 - Understanding .NET Assemblies
Do be aware, however, that if you click the newly rendered button, the graphical data will vanish (as the widget
Chapter 10 - Processes, AppDomains, Contexts, and Threads
is repainted to its default look and feel). If you wish to build a stylized widget that always renders itself in a
Chapter 11 - Type Reflection, Late Binding, and Attribute-Based Programming
unique manner, you may wish to build a custom Windows Forms control (see Chapter 15).
Part Four - Leveraging the .NET Libraries
Chapter 12 - Object Serialization and the .NET Remoting Layer
SOURCE The BasicPaintForm project is included under the Chapter 14 subdirectory.
Chapter 13 - Building a Better Window (Introducing Windows Forms)
CODE
Chapter 14 - A Better Painting Framework (GDI+)
Chapter 15 - Programming with Windows Forms Controls
Chapter 16 - The System.IO Namespace
Chapter 17 - Data Access with ADO.NET
Part Five - Web Applications and XML Web Services
Chapter 18 - ASP.NET Web Pages and Web Controls
Chapter 19 - ASP.NET Web Applications
Chapter 20 - XML Web Services
Index
List of Figures
List of Tables