Programming C#

Florian Rappl, Department of Theoretical Physics, University of Regensburg

Programming C#

Day 7: Drawing with GDI+, exception handling, resource management

Content

  • Drawing with GDI+
  • Images and image formats
  • User control drawing
  • Handling exceptions
  • The IDisposable interface
  • Releasing resources
  • Reflection

Drawing with GDI+

  • Windows has a drawing API called GDI
  • Windows Forms extends this API to GDI+
  • The central object is called Graphics
  • This object requires a target
  • This can be either an image or the screen
  • Images have advantages (buffering, modifying, ...)
  • Be aware that this requires a lot of memory

GDI+ methods (pt. 1)

  • Creating an image: var bmp = new Bitmap(400, 300)
  • Using it: var g = Graphics.FromImage(bmp)
  • Now we have access to methods that start with Draw and Fill
  • Draw / fill methods draw / fill the shape (border / content)
  • Drawing is done by a Pen (width, color)
  • Filling is done by a Brush (px→color)
  • Basic brush: SolidColorBrush
  • More advanced: LinearGradientBrush

GDI+ methods (pt. 2)

  • e.g. DrawRectangle() draws the border of a rectangle
  • e.g. FillEllipse() fills an ellipse (could be circle)
  • There are more advanced concepts like transformations
  • Here we set transformation matrices (translate, rotate, scale)
  • Also (quite complex) paths can be done
  • Such paths can create regions
  • We can apply operators (like union) on regions

→ Example - Drawing with GDI+

GdiPlus.zip

Images and image formats

  • There is a central abstract Image class
  • A more specialized version is the Bitmap class
  • The .NET-Framework knows several image formats (bmp, jpg, ...)
  • Images can easily be read or written to the filesystem
  • Image.FromFile() reads an image to an Image
  • Every instance has a Save() method

Drawing user controls

  • Several ways: A good way is to override OnPaint()
  • This method gives us an argument of type PaintEventArgs
  • The property ClipRectangle gives us the boundaries
  • Graphics gives us the graphics pointer
  • Another way is to create an event handler for the Paint event
  • Some controls (like the ListBox control) give us a third way
  • Set the DrawMode and create an event handler (for DrawItem)

→ Example - User control drawing

GdiControl.zip

Exceptions

  • We should always try to avoid exceptions
  • However, sometimes exceptions cannot be avoided
  • Example: Communication with the filesystem - OS throws exception
  • Hence we need a way to react to these exceptions
  • Rule: If an exception is possible, we should handle it
  • The construct is the same as in C++ (or Java)
  • Every exception inherits from the Exception class

Throwing exceptions

  • throw will throw an exception or re-throw the current exception
  • Throwing an exception will end the current code execution
  • Additionally the exception will bubble up
void Main() { "Before".Dump(); Sub(); "After".Dump(); }
void Sub() { "Enter".Dump(); throw new Exception("Bug"); }
//Dump() is an extension that is like Console.WriteLine()

Catching exceptions

  • So how to handle? Consider a try-catch block
  • try { /* try here */ } catch { /* catch here /* }
  • The try-block contains all (prob. failing) statements
  • The catch-block will be called if an exception occurred
  • Such a catch-block catches ALL possible exceptions
  • If we want or need access write catch (Exception ex) {}
  • Catch specific e.g. catch (FileNotFoundException) {}

Final actions

  • Sometimes we have code that depends on opening resources
  • No matter if an exception occurred or not we want to close those
  • This is where a finally {} block is useful
  • Now we can have try-catch, try-catch-finally or just try-finally
  • Also note that return in one block will still call the finally
try { "Try has been entered".Dump(); return true; }
finally { "Finally has been called".Dump(); }

→ Example - Exceptions

Exceptions.cs

The IDisposable interface

  • Many methods have to mark resources as being in use
  • The question is: How to release such resources?
  • Apparently the Close() method is important
  • When automatically releasing resources, how does the GC know?
  • The GC will automatically call the Dispose() method
  • The method is defined in the interface IDisposable
  • So this is our chance to tell the GC what to do
  • Additionally we have a destructor, but that is uninteresting

Releasing resources

  • We can explicitly release resources using a using construct
  • The syntax is quite close to foreach
  • We could also call Dispose() directly
using(var fs = new FileStream(/* ... */)) {
	/* Do something */
} // Resource automatically closed and freed

→ Example - Resource management

Reflection

  • Sometimes an instance of Type is required
  • We got that type with typeof() (at compile-time)
  • Or if we already had an instance: GetType()
  • This Type object contains all information about the type
  • We can find out what properties (names and types) are defined
  • Also what methods and events are available can be found
  • Or what interfaces are implemented and what's the base class

Using reflection

→ Example - Reflection

Reflection.zip

All available presentations

More questions? Just mail!

MVP

Florian Rappl, MVP Visual C#