Lesson 1 – Print Functionality

The PrintDocument Component

 

Creating PrintDocument object

 

How Printing Works

 

PrintPage event

 

// Method to handle PrintPage event

public void PrintElipse(object sender, System.Drawing.Printing.PrintPageEventArgs e)

{

  e.Graphics.DrawElipse(Pens.Black, e.MarginBounds);

}

 

 

Printing Content

 

PrintPreviewControl

 

myPrintPreview.Document = myPrintDocument;

 

 

myPrintPreview.InvalidatePreview();

 

 

PrintPreviewDialog

 

Printing Configuration

 

PrintDialog

 

PrintDialog1.ShowDialog();

 

PrintSetupDialog

 

Configure PageSetting at run time

 

Lesson 2 – Accessing and Invoking Components

.NET and COM Type Libraries

 

Web Service

 

public class AsyncDemo

{

     WebService1 myService;

     public void CallMethodAsynchronously()

     {

          myService = new WebService1();

 

          // Create AsyncCallback delegate

          System.AsyncCallback myCallback = new

System.AsyncCallback(CallBack);

             

              // Object required by method call but not

// used

myService.BeginMyMethod(myCallback, new

Object());

     }

 

     public void CallBack(IAsynResult e)

     {

          string myString;

          myString = myService.EndMyMethod(e);

     }

}

 

·        Must specify callback method, but don’t need to use it. Can receive data in same method by calling the End method. Program execution will halt at End call until result is available

 

Accessing Windows API

·        Most important functionality wrapped in .NET classes

·        Use DllImportAttribute to gain access to native functions

 

[System.Runtime.InteropServices.DllImport(“kernel32”)]

private static extern int Beep(int dwFreq, int dwDuration);

 

Lesson 3 Accessibility

Design

 

Program Accessibility

Support Standard System Settings

 

High Contrast

 

Keyboard Access

·        Document + make discoverable keyboard access to all app features

·        Provide shortcut keys to menu items

·        Set Tab order on dialogs

 

Notify Keyboard Focus Location

 

Do not rely on sound alone

 

Accessibility Properties

 

Lesson 4 – Implementing Help

The Help Class

 

Help.ShowHelp(MyForm, @”C:\myHelpFile.htm”, “HelpMenu”);

 

 

Help.ShowHelpIndex(MyForm,@”C:\myHelpFile.htm”);

 

HelpProvider Component

 

myHelpProvider.GetHelp(Button1);

 

Lesson 5 – Globalisation and Localisation

 

 

System.Threading.Thread.CurrentThread.Currentculture =

new System.Globalization.CultureInfo(“fr-CA”);

 

 

CultureInfo myCurrentculture =

CultureInfo.CurrentCulture;

 

Globalisation

 

Label1.Text = “$500”

 

Whereas setting to value formatted to currency will result in “£500” being displayed for en-GB – note no currency conversion takes place

 

Label1.Text = (500).ToString(“C”);

 

Localisation

 

 

 

Culture-Specific Formatting

 

CultureInfo modJPCulture = new CultureInfo(“jp-JN”);

modJPCulture.NumberFormat.CurrencySymbol = “$”;

Thread.CurrentThread.CurrentCulture = modJPCulture;

 

Right-to-left Display

 

Character Encodings

 

// Code page 932 represents Japanese chars

Encoding myEncoding = Encoding.GetEncoding(932);

 

 

// Obtain encoding instances

byte[] tgtData;

Encoding srcEncoding = Encoding.GetEncoding(932);

UnicodeEncoding tgtEncoding = new UnicodeEncoding();

 

// Convert legacy data (in mystring) to bytes

byte[] myData = srcEncoding.GetBytes(myString);

 

// Perform conversion

tgtData = Encoding.Convert(srcEncoding, tgtEncoding, myData);

 

 

UnicodeEncoding myEncoding = new UnicodeEncoding();

char[] myChars;

myChars = myEncoding.GetChars(myBytes);

 Framework Fundamentals

Lesson 1: Using Value Types

Built-in value types

Simplest types, e.g. Numeric, boolean

Still function as objects (e.g. Support for ToString(), etc.)

Contain data directly, stored on stack – rather than reference to data in heap.

Runtime optimises performance of 32-bit integers (Int32 and Uint32) – use these for counters and frequently accessed integral variables.

Double is most efficient floating-point type due to hardware optimisation.

Assignment between value types causes data to be copied (i.e. Two separate copies on stack).

Derived from System.ValueType



Declaration

To use must declare symbol as instance of required type.

Implicit constructor -> no need to use New keyword

Declare as nullable if want to determine if value has been assigned



Nullable<bool> b = null;

or

bool? b = null;



If nullable then HasValue and Value members are available



if (b.HasValue) Console.Writeline(“b is {0}”, b.Value);



User-defined types

Again store data on stack, but otherwise nearly identical to classes

Usually more efficient than classes

Should meet following criteria:

Composites of other data types that make working with related data easier, e.g. System.Drawing.Point contains X and Y integer properties to describe a location.

Define own types using struct keyword.

Note, new operator keyword to define operators within classes and structs, e.g.

Public static Cycle operator+(Cycle arg1, int arg2)

{

arg1.Value += arg2;

return arg1

}



Enumerations

Related symbols having fixed values, e.g.

enum Titles : int {Mr, Ms, Mrs, Dr };

Although value is an integer it is easy to output its symbol, e.g.

Console.WriteLine(“{0}”, Titles.Dr); // Displays “Dr”



Lesson 2: Using Reference Types

Built-in Reference Types

Most framework types

Store the address of their data (i.e. a pointer) on stack. Actual data stored in heap.

Heap memory managed by garbage collection.

Garbage collection occurs when needed or when triggered via
GC.Collect.
Optimised for applications where most data instances short lived, except for those allocated at start of application.

Assigning one reference variable to another creates a second copy of the reference to the same memory location in the heap as the original.

Derived from
System.Object

Strings

More than just data containers, also provide manipulation via their members, e.g.
System.String
provides members to work with text.



Instances of
System.Strings
are immutable. Any change to string causes a new string to be created and the old one abandoned. To void unnecessary temporary strings use string members
Concat
,
Join
or
Format
. Alternative use
StringBuilder
class to create dynamic (mutable) strings – most flexible as can div multiple statements.



Overrides
System.Object
operators.

Arrays

Declared by [], e.g.

int[] ar = { 3, 1, 2 };

Array.Sort(ar);

Streams

Mechanism to read / write to disk, communicate over network.

Derived from System.IO.Stream

Simplest = StreamReader and StreamWriter which provide access to text files. After processing call Close method so file does not remain locked, e.g.

StreamReader sr = new StreamReader(“test.txt”);

Console.WriteLine(sr.ReadToEnd());

sr.Close();

Exceptions

Unexpected events interrupting normal execution flow,e.g. Read large text file from removable disk and user ejects disk

Should never cause assembly to fail completely – should plan for them to occur, catch them and process appropriately.

try

{

StreamWriter sw = new StreamWriter(“text.txt”);

sw.WriteLine(“Hello, world!”);

sw.Close();

}

catch (Exception ex)

{

Console.WriteLine(ex.Messagge());

}



Base System.Exception class provides message and application data. Framework provides many derivations to describe different situations.

Can define own exceptions, these should derive from System.ApplicationException.

Runtime will execute first catch block with matching exception, so order them from most-specific to least

Finally block executes after try and any catch blocks. Use to close any streams and clean up after other objects that may be left open if exception occurs.

All code except simple variable declarations should be within try block.

Exception handling does incur slight performance penalty.



Lesson 3: Constructing Classes

Inheritance

Together with Interfaces helps provide consistency (e.g. Every class implements ToString())



e.g.

class DerivedException : System.ApplicationException

{

public override string Message{ get { return “Error”; } }

}



Can use derived classes interchangeably, e.g 5 classes derived from System.Drawing.Brush all of which can be passed to Gaphics.DrawRectangle that requires a Brush as one of its parameters.

Interfaces

A contract defining common set of members that all classes implementing interface must provide, e.g, IComparable defines CompareTo method allowing two instances of class to be compared for equality.

Class can implement multiple interfaces.

To implement follow these steps:

  1. 1 Create class declaration

class AClass

{

}

  1. Add interface declaration

class AClass : IComparable

{

}

  1. Right click on IComparable, select “Implement Interface” and then “Implement Interface” again. VS2005 will insert required skeleton methods.



Common interfaces

IComparable
implement if values can be ordered

IDisposable
permits manual disposal of object

IConvertible
convert class to be type, e.g.
boolean
,
byte

ICloneable
copy an object

IEqutiable
compare 2 instances for equality

IFormattable
convert value to specially formatted string

Partial Classes

Split class definition across multiple files.

Benefit = hide details of class definition so derived classes can focus on most significant potions.

Form class = example. Previously all form designer generated code in class. Now this code is hidden in

form
.Designer.cs file.

Generics

Allow definition of type while leaving some details unspecified. Instead of specifying parameter types can leave clients to specify them.

Several classes found in System.Collections.Generic namespace.

Why Use

Previously developers used Object class to achieve similar functionality.

2 significant advantages

  1. Reduced run time errors
    . Compiler can't detect type errors when casting to / from objects. Only find problem at runtime when exception raised

  2. I
    mproved performance
    . Casting requires boxing.

Creation

class Gen<T, U>

{

public T t;

public U u;



public Gen(T _t, U _u)

{

t = _t;

u = _u;

}

}

Class has two members of type T and U. Consuming code determines these types.

Generic code only valid if will compile for every possible instance of it, i.e. Limited to capabilities of Object class – call ToString, GetHasCode, but not + or > operator. These restrictions do not apply to the consuming code,

Consumption

Gen<double, int> gb = new Gen<double, int>(10.25, 2005);

Console.WriteLine(gb.t + gb.u);

Constraints

Overcome restrictions on limiting capabilities to that of the Object class. Support for 4 types:

w
here T : IComparable

w
here T : SomeClass

w
here T : new()

w
here T : struct

Events

Message sent by object to signal occurrence of action – could be caused by user interaction, or program logic.

Object raising event = event sender

Object capturing event = event receiver

Event sender does not know which object will receive events it raises. This requires pointer like functionality to link source and receiver – provided by Delegate.

Delegate

Class holding reference to method.

Unlike other classes it posses a signature and can only reference methods matching its signature.

Equivalent to type safe function pointer.

Delegate declaration defines delegate class – declaration provides signature whilst runtime provides implementation, e.g.

public delegate void AlarmEventHandler(object sender, EventArgs e);

Standard event handler signature (above) defines method that does not return a value, whose first parameter refers to the instance raising the event and second parameter is a class derived from
EventArgs
that holds the event data.

If event does not generate data then second parameter = instance of
EventArgs
, otherwise it is instance of derived class.

EventHandler
= predefined delegate for event that does not generate data. If event does generate data then must provide own delegate (see above).

To associate event with handler, add instance of delegate to the event – as follows:

public void button1_Click(object sender, EventArgs e) { }

this.button1.Click += new System.EventHandler(this.button1_Click);

Example using custom
EventArgs
and generic
EventHandler

public class CustomEventArgs : EventArgs {}



public class Publisher

{

public event EventHandler<CustomEventArgs> ce;



public void Go() {OnRaiseCE(new CustomEventArgs());}



protected virtual void OnRaiseCE(CustomEventArgs e)

{

// temp copy to avoid race condition where

// subscriber unsubscribes between

// null check and event being raised

EventHandler<CustomEventArgs> handler = ce;



if (handler != null) handler(this,e);

}

}



public class Subscriber

{

public void Subscriber(Publisher p){p.ce += HandleCE;}



public void HandleCE(object sender, CustomEventArgs e) {}

}

Attributes

Describe a type or property in way that can be programmatically queried via reflection.

Common uses include:

[assembly: AssemblyTitle(“ch01cs”)]

Derive from
System.Attribute

Visual Studio automatically creates some attributes (such as title, description, version, etc.) when project created – these should be edited as the defaults may not contain desired information (e.g. Description will be blank)

To enable a class to be serialized must include
[Serializable]
attribute.

The following attribute declares that the class needs to read
c:\boot.ini
. The runtime will throw an exception prior to execution if it lacks specified privilege.

[assembly:FileIOPermissionAttribute(SecurityAction.RequestMinimum, Read=@”
C:\boot.ini
]

Type Forwarding

The attribute
[assembly:TypeForwardedTo()]
allows a type to be moved from one assembly into another without clients of the first assembly having to be recompiled.

Follow these steps to move TypeA from source to destination class library:

  1. Add TypeForwardedTo attribute to source file for TypeA in the source class library assembly

using System.Runtime.CompilerServices;

[assembly.TypeForwardedTo(typeof(DestLib.TypeA))]

  1. Cut the definition of the type from the source file in the source class library assembly

  2. Paste typeA definition into destination class library assembly

  3. Rebuild both libraries

Lesson 4: Type Conversion

VB vs C#

VB allows implicit conversions, C# prohibits implicit conversion that loose precision.

To turn off implicit conversion in VB add Option Strict On to top of each source file.

Both VB and C# permit implicit conversion if destination can accommodate all possible source values (called a widening conversion)

If the range of the source exceeds the destination (a narrowing conversion) then explicit conversion is required:

Narrowing conversion may return incorrect result if source value exceeds destinations type range. If conversion between types not defined then compile-time error generated.

Boxing & Unboxing

Boxing converts value to reference type, e.g.

int i = 123;

object o = (object) i;

Unboxing converts reference to value type.

object o = 123;

int i = (int) o;

Incur overhead so avoid using in repetitive tasks.

Boxing occurs when call virtual methods that a structure inherits from System.Object (e.g. ToString).

How to avoid

Implement type specific overloads for procedures accepting various value types

Use generics whenever possible

Override ToString, Equals and GetHash virtual members when defining structures.

Conversion in Custom Types

public struct TypeA

{

public int Value;



// Implicit conversion from an int

public static implicit operator TypeA(int arg){}

// Explicit conversion to an integer

public static explicit operator int(TypeA arg){}

}