Document Sample
CSharp Powered By Docstoc
					                                        Introduction to C#

Course Syllabus – Winterim 2003

   I’ll assume you know some C++ and/or Java
   It’s only 1 credit, so don’t expect to come out as experts – but we’ll cover a lot!
   Double up on computers – Least experienced person should be the “driver”
   Audit: For an “S”, must do one of the following:
         o Attend 12 or more hours of class
         o Attend 6 or more hours of class and turn in 1 successful program
         o Turn in 2 successful programs
   For Credit:
         o Attend 12 or more hours of class
         o Two graded programs

   Note: Some material from the first 12 pages of these notes was gleaned from the C# Language
    Reference Manual, October 2002 draft, produced by ECMA TC39/TG2

Hello World Program
using System;                  // Won’t need to write System.Console
namespace HelloWorld           // Not required to put in a namespace
    class Hello
       static void Main()
          Console.WriteLine("Hello world!");

Exercise 1

   Start Visual Studio .NET
   Click New Project, Select Visual C# Projects, Use the Console Application Template
   Store in Location C:\Temp and make the name: HelloWorld, then click OK
   Type in the Console.Writeln statement after the TODO:
   Save, Build, Run (Debug/Start Without Debugging)

   Notes:
       o     No #include or import: have using clauses instead
       o     Main start with a capital M
       o     The parameter to Main is similar to Java, but unlike Java, it’s not required.
       o     C# has the concept of namespace
       o     Namespace is similar to Java packages, but doesn’t have to follow folder names
C# Overview
Some similarities with C++ and Java
 Same comments: // and /* */
 Has “preprocessing” directives for conditional compilation similar C++ (but not preprocessed)
 Statements terminated with semicolon
 As in Java, all variables and functions (methods) go inside classes (also in structs in C#)
 Declarations of simple types: int a; int b = 6;
 Constants are similar to C++: const float PI = 3.1415926f; // static but can’t say static
 Assignment:      x = 4; z = (x + y) / 4;
 Braces for block statements: statements between { and }
 Conditionals must be bool expressions, similar to Java - more restrictive than C++ (int)
 If statements: if ( bool expression ) some_statement_or_block_statement
 While statements: while ( bool expression ) some_statement_or_block_statement
 For statements: for ( int i = 0; i < n; i++ ) some_statement_or_block_statement
 Statements “do while” and “switch” are still there, although switch is changed slightly
 Some of the same operators
           Arithmetic operators: + - * / %             Given integer n, the last digit of n is: n % 10
           Relational operators: < <= > >= == !=
           Logical operators: && || !
           DeMorgan's Laws: !(A&&B) = (!A||!B)                      !(A||B) = (!A&&!B)
           Bitwise: <<               >> | & ^ ~
           Others: ++ -- += -= /= *= /= %= <<= >>= &= ^= |=

All operators, by precedence
   Category              Operators
   Primary               x.y f(x) a[x]                     x++ x-- new
                         typeof checked                    unchecked
   Unary                 +    -        !     ~    ++x       --x   (T)x

   Multiplicative        *    /        %

   Additive              +    -

   Shift                 <<   >>

   Relational and        <    >        <=    >=       is    as
   Equality              ==       !=

   Logical AND           &

   Logical XOR           ^

   Logical OR            |

   Conditional AND       &&

   Conditional OR        ||

   Conditional (right)   ?:

   Assignment (right)    =    *=        /=       %=    +=    -=    <<=   >>=   &=   ^=   |=

C# Types

   C# supports two kinds of types: value types and reference types.
       o Value types include simple types (e.g., char, int, and float), enum types, and struct types
       o Reference types include class types, interface types, delegate types, and array types.
   Unified type system: Everything descends from the base type object, even the simple types
   The simple types can be used like in Java & C++, but are really structs
   For variables whose type is a class, they are used like in Java ( no -> )
       o MyClass m = new MyClass();                       m.DoIt();
       o C# has automatic memory management

The table below lists the predefined types, and shows how to write literal values for each of them.
    Type        Description                                           Example
    Object      The ultimate base type of all other types             object o = null;
    String      String type; a string is a sequence of Unicode code   string s = "hello";
    Sbyte       8-bit signed integral type                            sbyte val = 12;
    short       16-bit signed integral type                           short val = 12;
    int         32-bit signed integral type                           int val = 12;
    long        64-bit signed integral type                           long val1 = 12;
                                                                      long val2 = 34L;
    byte        8-bit unsigned integral type                          byte val1 = 12;
    ushort      16-bit unsigned integral type                         ushort val1 = 12;
    uint        32-bit unsigned integral type                         uint val1 = 12;
                                                                      uint val2 = 34U;
    ulong       64-bit unsigned integral type                         ulong   val1   =   12;
                                                                      ulong   val2   =   34U;
                                                                      ulong   val3   =   56L;
                                                                      ulong   val4   =   78UL;
    float       Single-precision floating point type                  float val = 1.23F;
    double      Double-precision floating point type                  double val1 = 1.23;
                                                                      double val2 = 4.56D;
    bool        Boolean type; a bool value is either true or false    bool val1 = true;
                                                                      bool val2 = false;
    Char        Character type; a char value is a Unicode code unit   char val = 'h';
    decimal     Precise decimal type with 28 significant digits       decimal val = 1.23M;

   Each of the predefined types is shorthand for a system-provided type
        o For example, the keyword int refers to the struct System.Int32
   int expressions are considered == if they represent the same integer value
   object expressions are == if both refer to the same object or both are null
   Strings are == if they have identical lengths and identical characters or both are null

Arrays in C#
   Arrays in C# are similar to arrays in Java
       o objects with a Length (and other properties and methods)
       o Allocate using new
   Some examples:
        int[] a1 = new int[5];            // 1-D array
        String s = Console.ReadLine();    // Assume one int on the line
        a1[0] = int.Parse(s);             // int is a struct with methods!
        int[] a2 = new int[] {1, 2, 3}; // initializer
        Console.WriteLine(a2.Length);     // Writes out 3
        int[,] m1 = new int[3,4];         // 2-d rectangular array
        int[,] m2 = new int[,] {{1, 2, 3}, {4, 5, 6}};
        int[][] r = new int[2][];         // ragged (jagged) array
        r[0] = new int[5];    r[1] = new int[7];

Methods and Parameter Passing
   Functions (methods) are similar to C++ and Java
   C# has value, reference, and output parameters
   Note in example below, member data are not usually passed to the methods! For illustration only.
   Note the argument placeholders in Console.WriteLine.

    using System;
    class MethodExample
       int x = 3, y = 7, z;
       int[] a = new int[3];

        void Run()
           DoIt(x, ref y, out z, a);
           Console.WriteLine("Values: {0} {1} {2} ", x, y, z); // 3 8 5
           Console.WriteLine("Array: {0} {1} {2} ", a[0], a[1], a[2]); // 2 3 0

        void DoIt( int a, ref int b, out int c, int[] x )
           c = 5; // Must be assigned before used, otherwise compile error
           Console.WriteLine("Values: {0} {1} {2} ", a, b, c); // 4 8 5
           x[0] = 2; x[1] = 3;

        static void Main()
           new MethodExample().Run();

Exercise 2
Write a console program that reads in 5 integers from the standard input (1 int per line), then calculates
and prints the number of integers greater than the average. Use at least 3 functions (methods).


   Class declarations define new reference types
   Non-nested class declarations default to internal declared accessibility
   A class can inherit from another class, and can implement interfaces
   Class members can include constants, fields, methods, properties, events, indexers, operators,
    instance constructors, destructors, static constructors, and nested type declarations
   Member Accessibility:
    Accessibility    Meaning
    Public           Access not limited
    Protected        Access limited to the containing class or types derived from the containing class
    Internal         Access limited to this program
    Protected        Access limited to this program or types derived from the containing class
    Private          Access limited to the containing type (default member accessibility for classes)

   Constants: use const and are compile time and static (unlike Java’s final)
       o public const int MyConst = 1;

   Fields: represent a variable associated with an object or class
        o Can be designated as static or readonly (or both or neither)
        o private int x;
        o public readonly int y; // Since not defined here, must be defined in a constructor
        o public static int z;

   Methods: can be static or non-static. Can be overloaded: signatures must differ
       o For non-static methods, this is a reference to the object the method was invoked with

   Properties: provides access to a characteristic of an object or a class
       o Have get and set accessors that specify what to do when their values are read or written
       o User can treat it as if it were a field: myButton.Caption = “Click on Me!”;
       o Can have just set or get to make property write only or read only

              private string caption;
              public string Caption
                    return caption;
                    caption = value;                  // value is a keyword: right hand of assignment

   Events: used to provide notifications
       o Event declaration must be a delegate type
       o A delegate is like a function pointer in C++: it’s actually a function reference
       o The user can only add ( += ) and remove ( -= ) a handler to/from an event
       o Below is an event example: Actually, there is another example within the example!

using System;
using System.Timers;

public delegate void MyEventHandler(int x);             // declares a type “reference to function”
class EventExampleComponent
   public event MyEventHandler theEvent = null;

    private Timer aTimer;       // Make a timer
    private int x = 1;

    public EventExampleComponent()
       // Make a timer and start it up
       aTimer = new Timer();
       aTimer.Interval = 1000;       // 1 second
       aTimer.Enabled = true;        // Start it up

        // Add an event handler for the timer Elapsed event
        aTimer.Elapsed += new ElapsedEventHandler( MakeItHappen );

    public void MakeItHappen(object source, ElapsedEventArgs e)
       if(theEvent != null )
          theEvent(x++); // Calls all event handlers attached to theEvent

class EventDemo
   private EventExampleComponent eec = new EventExampleComponent();

    public void Handler1( int x ) { Console.WriteLine(x); }
    public void Handler2( int x ) { Console.WriteLine(x * x); }

    // Can   only   use += and -= on   eec.theEvent
    public   void   AttachHandler1()   { eec.theEvent    +=   new   MyEventHandler(Handler1);        }
    public   void   AttachHandler2()   { eec.theEvent    +=   new   MyEventHandler(Handler2);        }
    public   void   RemoveHandler1()   { eec.theEvent    -=   new   MyEventHandler(Handler1);        }
    public   void   RemoveHandler2()   { eec.theEvent    -=   new   MyEventHandler(Handler2);        }

    static void Main()
       EventDemo ed = new EventDemo();
       // Will write out 1 1 2 4 3 9 4 16 ... two numbers every second
       Console.WriteLine("Press Enter to Quit");
       int ch = Console.Read();
   Indexers: Allow an object to be indexed as an array

class MyContainerClass
   . . .
   public object this[int index]
      get { . . . }
      set { . . . }
 . . .

If this is written right, then user can say:
    MyContainerClass m = new MyContainerClass();
    . . .
    m[2] = . . .
    x = m[1];

   Operators: C# has operator overloading, but a little different than C++
       o Must be public and static
       o Must have “right” number of parameters (in C++, “this” can be one, e.g., LHS)
       o Can’t overload assignment: assignment is always bit-wise copy
       o public static MyClass operator* ( MyClass x, MyClass y ) { ... }

   Instance Constructors: Used to initialize instances. Same rules as C++ and Java
        o Can have more than one, if signatures differ
        o If none, default one is supplied (no parameters)

   Destructors: Specify the actions required to destruct an instance
       o no parameters, no accessibility modifiers, can’t be called explicitly
       o Called by garbage collector
       o Declaration like C++:        ~MyClass() { . . . }

   Static Constructors: Specify actions required to initialize a class
        o no parameters, no accessibility modifiers, can’t be called explicitly: called automatically
        o static MyClass() { . . . }

Inheritance & Polymorphism

   A mix between C++ and Java, plus new rules
   Single inheritance only
   Don’t specify public, private, or protected like in C++ - Just put colon and name of parent class
   If an not an explicit direct base class, then implicit direct base class is object
   A sealed class can’t be derived from
   Derived class implicitly contains all members of base class except for the constructors & destructor
   Must declare methods as virtual to get polymorphism
   Methods, properties, and indexers can be virtual
   Descendant class must specify virtual overridden methods using override keyword
   Methods and classes can be declared abstract
   Use the keyword base to call the parent
   A call to base or this goes before the body, with the default being base() if it’s missing
   If a method isn’t virtual and is overridden in a child class, parent’s method becomes “hidden”
         o Will get a compiler warning
         o Can get rid of warning by declaring it new

class A
{ . . .
   public A( int z ) { . . . }
   public virtual void F() { . . . }
   public void H() { . . . }

class B: A
   public B( int z        ) : base(z) { . . . }
   public override        void F()
      . . .
      base.F();           // optional call to the parent’s F()
      . . .
   new public void        H() { . . . }                // warning without the new

abstract class C
   public abstract void G();                        // No body

sealed class D           // can’t derive from D
{    . . . }

Exercise 3
Write a part of a Complex class (private real and imag double data) with an instance constructor that
takes a real and imag, properties for Real and Imag with get and set accessors, an operator+ , and
overrides object’s: public virtual string ToString(); // to make a string like (3.4,7.2)
Write a console test-bed Main to test the Complex class with the following lines:

           Complex z1 = new Complex( 3.7, 2.8 );
           Complex z2 = new Complex( -1.6, 3.14 );
           Console.WriteLine( "Sum of " + z1 + " + " + z2 + " is: " + (z1 + z2) );
           z1.Real = 1.6;
           Console.WriteLine( "Real of " + z1 + " is: " + z1.Real );

The output should be:
       Sum of (3.7,2.8) + (-1.6,3.14) is: (2.1,5.94)
       Real of (1.6,2.8) is: 1.6

   Similar to classes in most ways except structs are:
       o value types not reference types
       o never abstract
       o always implicitly sealed (can't be inherited from)
       o stored “on the stack" – not “new’ed” on the heap (but can be)
       o member accessibility is public, private, or internal – default is internal
       o a struct is not permitted to declare a parameterless instance constructor
       o A struct can’t have a destructor
       o A struct instance constructor is not permitted to include a call to base(…)
       o Instance member functions can’t be called until all fields have been definitely assigned

   Implications:
       o A variable of a struct type directly contains the data of the struct, whereas a variable of a
           class type contains a reference to the data.
       o Assignment to a variable of a struct type creates a copy of the value being assigned. This
           differs from assignment to a variable of a class type, which copies the reference but not the
           object identified by the reference.
       o Similar to an assignment, when a struct is passed as a value parameter or returned as the
           result of a function member, a copy of the struct is created. A struct may be passed by
           reference to a function member using a ref or out parameter.
       o Every struct implicitly has a parameterless instance constructor, which always returns the
           value that results from setting all value type fields to their default value and all reference
           type fields to null

public struct Point
   public int x, y;
    public Point(int init_x, int init_y)
       x = init_x;
       y = init_y;

If you declare an array, it contains Point values, not point references:

       Point[] points = new Point[100];

    An interface defines a contract
    A class or struct may implement multiple interfaces
    An interface may inherit from multiple base interfaces
    Interfaces can contain methods, properties, events, and indexers
    It can’t contain constants, fields, operators, constructors, destructors, types, or static members
    Members are all “abstract”, but not designated that way
    All interface members implicitly have public access
    Interface member declarations can’t include any modifiers

public delegate void StringListEvent(IStringList sender);
public interface IStringList
   void Add(string s);                        // method
   int Count { get; }                         // property
   event StringListEvent Changed;             // event
   string this[int index] { get; set; }      // indexer
public MyClass: IStringList
   // Must provide bodies for all interfaces
   public void Add(string s) { . . . }
OR void IStringList.Add(string s) { ... } // Can only call via interface (cast to IStringList)
    . . .

Exercise 4
Re-implement Complex as a struct. Make a ComplexList class that implements the
System.Collections.ICollection interface. It has a private array of Complex and a count of the number
of elements currently stored in the in the list. Have a method to add a complex number to the end of
the list. Make an indexer. Write a Main to test all this. Note: It takes some digging to find the
methods for ICollection, since it inherits. Put null and/or simple bodies for everything but the Count
property. If you finish early: 1) add a method to remove an element 2) make the list growable.

 Declares a set of named constants
    Has a corresponding integral underlying type, the default is int
    Derives from class System.Enum (child of System.ValueType, which is child of object)
    Each is a distinct type - explicit conversion is required to convert between it and integers
    Any value of the underlying type can be cast to the enum type, and is a distinct valid value
    Can use operators: ==, !=, <, >, <=, >= , + , - , ^, &, | , ~ , ++, -- , and sizeof

public enum Color: int
    Green = 10,
Then Color.Red is 0, Color.Blue is 11.


   object-oriented, type-safe function references
   A delegate declaration defines a class derived from System.Delegate
   Delegate types are implicitly sealed (System.Delegate is not a delegate type!)
   A delegate instance encapsulates one or more methods known as callable entities
   The set of methods encapsulated by a delegate instance is called an invocation list
   Delegates are combined using the binary + and += operators
   Delegate are removed using the binary – and -= operators
   Delegate types are name equivalent, not structurally equivalent – 2 can have same “signature”
   anonymous” invocation – doesn’t know about the classes of the methods it encapsulates
   three steps in defining and using delegates: declaration, instantiation, and invocation

public delegate void D(int x);
public class Test
     public static void M1(int             i) { . . . }
     public static void M2(int             i) { . . . }
     public void M3(int i) { .             . . }
class Demo
   static void Main()
      D cd1 = new D(Test.M1);
      cd1(-1);                              // call M1
      D cd2 = new D(Test.M2);
      D cd3 = cd1 + cd2;
      cd3(10);                              // call M1 then M2
      cd3 += cd1;
      cd3(20);                              // call M1, M2, then M1
      Test t = new Test();
      D cd4 = new D(t.M3);
      cd3 += cd4;
      cd3(30);                              // call M1, M2, M1, then M3
      cd3 -= cd1;                           // remove last M1
      cd3(40);                              // call M1, M2, then M3
      cd3 -= cd4;
      cd3 -= cd2;
      cd3 -= cd2;                           //   impossible removal is benign
      cd3(60);                              //   call M1
      cd3 -= cd1;                           //   invocation list is empty
      cd3(70);                              //   System.NullReferenceException thrown

If such a delegate invocation includes reference parameters, each method invocation will occur with a
reference to the same variable. If the delegate invocation includes output parameters or a return value,
their final value will come from the invocation of the last delegate in the list.


   try, catch, throw: similar to Java (and to some extent, C++)
   All exceptions must be represented by an instance of a class type derived from System.Exception
   A finally block can be used for code that executes both in normal and exceptional conditions
   Several predefined in System, such as NullReferenceException, ArithmeticException, etc.

    . . .
catch ( System.ArithmeticException e )
   . . .
catch ( System.Exception e )                // catches any descendant of Exception
   . . .
catch    // catches anything, even exceptions from other code like C++ that don’t descend
   . . .
   . . .

abstract             as                    base                  bool                 break
byte                 case                  catch                 char                 checked
class                const                 continue              decimal              default
delegate             do                    double                else                 enum
event                explicit              extern                false                finally
fixed                float                 for                   foreach              goto
if                   implicit              in                    int                  interface
internal             is                    lock                  long                 namespace
new                  null                  object                operator             out
override             params                private               protected            public
readonly             ref                   return                sbyte                sealed
short                sizeof                stackalloc            static               string
struct               switch                this                  throw                true
try                  typeof                uint                  ulong                unchecked
unsafe               ushort                using                 virtual              void
volatile             while

GUI Windows Applications

   New Project, C#, Windows Application
   Similar to Visual Basic, but use C#
   Lots of Windows – need to develop your own way of organizing them
        o Designer – Has forms on which you can place controls
        o ToolBox – Contains controls that can be placed on the forms
        o Properties Window – Design-time properties of the components
        o Code Window
   Drag a component from the ToolBox and put it on the Form
   Use help to find out about the component – press F1 with the component selected
   When you type a variable followed by a period, a list a properties, methods, etc. appears
   Use the Properties window to change the name, text, or other properties of a component
   Double click on a Button component to add code for a button handler
   In the Properties Window, if you select events (Lightening Bolt icon near the top of the window),
    then you can double click on the white space to the right of an event to add a handler for it

Exercise 5
Make the form below. It has a Label, ListBox, TextBox, and 2 Buttons.
Clicking the “Add String” button should add the string in the TextBox to the list, if the string doesn’t
have a zero length. Clicking the “Delete Selected String” button should delete the selected string, if
there is one. Use “help” to find appropriate methods and properties for the ListBox and TextBox.

Some hints:
 1. Use the Text property for TextBox
 2. Use the Items property for ListBox – it’s of type ListBox.ObjectCollection
 3. Use the Add method of the ListBox.ObjectCollection
 4. Use the SelectedItem or SelectedIndex method of ListBox
 5. Use the Remove or RemoveAt method of ListBox.ObjectCollection

File I/O

   In the namespace: System.IO
   Aren’t required to try-catch, as you are in Java

   FileStream class
        o A constructor: public FileStream( string path, FileMode mode, FileAccess access)
               enum FileMode: Create, Append, Open, OpenOrCreate (and others)
               enum FileAccess: Read, ReadWrite, Write
        o Can read and write single byte or arrays of bytes

   StreamWriter class
        o A constructor: public StreamWriter(string path, bool append);
        o Lots of Write and WriteLine methods for many different types to output

   StreamReader class
        o A constructor: public StreamReader(string path);
        o Can read single byte or arrays of bytes
        o Can read a line a text: ReadLine() returns a string
              Up to line feed ("\n") or a carriage return, line feed ("\r\n").
              Returned string doesn’t contain the terminating carriage return or line feed
              Returns null if the end of the input stream is reached.
        o Can use string and primitive type Parse methods to get out data
              The Split method of String is good for parsing and tokenizing!

StreamWriter outstream = new StreamWriter(“outfile.txt”);
outstream.WriteLine( “Hello” );

StreamReader instream = new StreamReader(“infile.txt”);
bool done = false;
while ( ! done )
   String s = instream.ReadLine();
   if ( s == null )
      done = true;
      // Process the string

Message Box

The MessageBox class has about a dozen overloaded static Show methods. Three examples:

MessageBox.Show( "Some Strange Error!" );
MessageBox.Show( "Contact Somebody", "Some Strange Error!" );
MessageBox.Show( "Want To Go?", "Party Tonight", MessageBoxButtons.YesNo );

Exercise 6
Make the form below with a TextBox, MainMenu, OpenFileDialog, SaveFileDialog.
MainMenu should have “Open”, “Save”, and “Exit”.
For the TextBox, set: MultiLine to true, WordWrap to false, ScrollBars to both
For the SaveFileDialog and OpenFileDialog, set:
                Filter for only text (TXT) files
                InitialDirectory to a period (current directory)
If the SaveFileDialog is called saveFileDialog1, then you can use it as (similar for OpenFileDialog):

       if( saveFileDialog1.ShowDialog() == DialogResult.OK )
           // do something with saveFileDialog1.FileName

    When the Open menu item is chosen, clear the TextBox, read in the lines from the selected file
      and put them in the TextBox. Hint: textBox1.AppendText( s + "\r\n" );
    When the Save menu item is chosen, write out the lines of the TextBox to the chosen file.

Some “Enhancements” to work on if you finish early:
   1. Put on a Clear button to clear the textbox
   2. Put an option to append to the file when saving (e.g., radio button or checkbox)
   3. Put an option to append to the TextBox when reading (try a different way than in 1)
   4. Number the lines as you read them in from the file and put them into the TextBox
   5. Number the lines as you write them out to the file
   6. Put a nice picture on the form somewhere (PictureBox)
   7. Put on a PrintDialog
   8. Put in a Timer and add random text to the TextBox every time the timer goes off
   9. Open binary files and display results in hex

Manipulating Databases – Introduction

   Let’s look at OLE DB providers – we won’t talk about SQL servers
   We’ll look at two ways of interfacing to databases: easy and super-easy!

   In either, first you can connect to the database in the server explorer (not required, but easier)
        o From the Tools menu, select “Connect to Database”
        o Select the Provider tab and select the provider – we’ll assume Microsoft Jet
        o Select the Connection tab and put in the database name (can browse to it)
        o Click “Test Connection” to make sure everything went ok

   Easy Way to interface to the database
       o From Toolbox/Data, select OleDbDataAdapter and drag it to the form: A wizard comes up
               Click Next after reading and after each of the steps that follow
               Select the database you connected to above (could have done the connection here)
               Select “Use SQL statements”
               To load the data, select “Query Builder”, unless you are quite handy at SQL
                       Choose the tables, fields, and other data selection criteria
       o After successfully finishing above, an OleDbConnection is automatically made for you
       o Assuming your form is visible, select “Generate Dataset” from the Data menu item
               Choose a name for the DataSet
               Choose which tables to add to the dataset
       o The Data Adapter is used to exchange data between the database and the DataSet
               Read data from the database into the DataSet
               Write changed data from the DataSet back to the database
       o Put components on the form that can be used to display/edit the data
               A DataGrid can handle all the fields using a grid format
       o Use methods and properties of the generated code to populate the components
               A DataSet class is made for you that encapsulates the tables
                       It gives nice and easy access to most things
               Load Data: Pass the dataset variable to the Fill method of the Data Adapter variable
               Getting at Data in the tables is easy
                       The generated DataSet object has a property for each table
                       An indexer is made for the table property, that gets at each row
                       For each row, there is a property for each column
                       Suppose dataSet1 variable, with Contacts table, and First_Name field
                       To get at the First_Name of the first data record:
                              o dataSet1.Contacts[0].First_Name
                       To get the number of rows in the table:
                              o dataSet21.Contacts.Count

   Super Easy Way to interface to the database
       o Select “Add New Item” (from File or Project) and choose “Data Form Wizzard”
       o Select “Create New Dataset” and give it a name
       o Select the database you connected to above
       o Add the tables you want
       o Choose the columns you want
       o Specify Grid or Individual Controls

Exercise 7
Copy samp1.mdb (I’ll let you know where it’s at) to your project directory.
Make a Windows Application whose main form looks like:

Connect to the Samp1.mdb database.

For the first two buttons:
        Use the “super easy” method specified on the previous page to make a DataForm with a Grid
        and another DataForm with individual controls. Have the first two buttons make one of these
        forms (make an instance variable and do “new”) and bring it up. Make one of them display as
        a modal dialog (ShowDialog method) and the other as a Modeless dialog (Show).

For the third button:
    Make another Windows Form (Project/AddWindowsForm)
    Put a ListBox on the form
    Use “easy” method to add an OleDbDataAdapter, OleDbConnection, and DataSet to the form
    Make a LoadIt method for the form that:
            o Clears the list box
            o Fills the DataSet (use Fill method of Data Adapter)
            o Adds all the names in the database to the list, format: first_name <space> last_name
    Call the LoadIt method at the end of the form constructor
    To show a Form2 from the main form: new Form2().ShowDialog();

If you finish early: There appears to be bugs in the “Super Easy – Separate Controls” when using the
Add button and Cancel All Button. Go into code and try to fix them! What I did for Add: Look at
replacing the “AddNew” call with direct manipulation of the DataSet object. Is there an easier way???
Crystal Reports

   Relatively easy way to create reports from a data source
   Select “Add New Item” (from File or Project) and choose “Crystal Report”
   The “Do you want to register” annoyingly comes up ALL the time
   You can use the Report Wizard or start with a blank report
   Report Wizard
        o Choose data sources and specify tables in reports
        o Choose fields to display
        o Choose how you want it grouped, totaled, and/or any other options you want
   Blank Report or changes to a wizard-generated report
        o Use the toolbox and Field Explorer: semi-intuitive, but sometimes a pain
        o ToolBox: make boxes, lines, text
        o Field Explorer
                  Parameter Fields let you specify “variables” (but see annoyances below)
                  You can specify running totals and/or other formulas
                  You can specify the grouping
        o The Select Expert lets specify which records to show
                  Can use it with a Parameter Field
   A Crystal Report Component can be placed on a form from the Toolbox
        o Set the “ReportSource” property to a report you’ve created via above
        o You can also set the SelectionFormula: at design time or at run time
                  Can get around some annoyances listed below
                  The text needs to be of the form: {table.field} = “item”
                         Example: {Contacts.Last Name} = "Johnson"
                         Remember to make a quote inside quote in C# (or Java or C++): \”
                         Above would be:
                                 crystalReportViewer1.SelectionFormula =
                                            " {Contacts.Last Name} = \"Johnson\"" ;
                         Can have more than one if and them together
   Some other annoyances
        o In this version bundled with .NET, databases have hard-coded paths in the reports
                  The “real” version has a “same folder” option
                  You can get around this by having the Application open the report at the start,
                    change the database it points at, delete the report, and save back the changed report,
                    but this is rather an ugly way to do it. (Maybe somebody know of a better way?)
        o For a parameter field (it’s like a variable, useful in making selection criteria), when you set
            default values from a field in a table, it is tied to those values at design time. If the table
            changes at run-time, the list of choices doesn’t change. Would be MUCH better if the
            choices were always automatically tied to the current entries in the database table. You can
            set the parameters field “pick list” at run time. They have example code showing how in
            their help files. What they don’t show is that in most “useful” examples, you need to open
            the database, loop through the values of a given field, and add those to the list. So you
            might as well make your own controls for selection and fill those. You have more control
            over how they look. And that is where you can use the “SelectionFormula” field of the
            Crystal Report component. I suppose if you got in to programming the Crystal Reports….
        o If anyone knows of better ways around these, let me know. I haven’t used this all that
            much and what I have done was by trial and error, mostly error!
Exercise 8

This program is going to use the Samp1.mdb database and makes a report from it. The main form
should have a ComboBox, Button, Label, OleDbDataAdapter, OleDbConnection, and DataSet.

The DB components are connected to the database as before.
First, remove all existing data connections (Server Explorer), copy Samp1.mdb to your folder for this
project, and make a new connection for it (just for practice!).

Load the ListBox with the names from the database.
You can set the Sorted property to true at design time.
Also, set the DropDownStyle to DropDownList.

Put the code to load it in the event handler for the Activated Event (in the event list for the form,
double-click on the white part to the right of the Activated event).
Set the SelectedIndex property here also.

   Try making the Crystal Report from a blank report – it doesn’t have to be pretty
       Project / Add New Item / CrystalReport and choose to do a blank report
       In the Field Explorer, right click on Database Fields and Add/Remove database to add the
         database and fields (from Database Files)
       For Report Options, display Date/Time fields as Dates
       Put a Nice Text Object for the Report Header – change it to a large font
       Put the Selected Name in the Page Header
       In the details, put the Field Data and Text Descriptors
              o For Field Data, select a database field in the Field Explorer, then right-click on the
                  details section and select Insert Field

   Put the Report Viewer on a separate form

When “View Report” is clicked on the main form, a report with the data for the person with the
selected name should be brought up. Before you show the report form, you need to use the selected
item in the ComboBox to set the ReportViewer SelectionFormula Property.
Make a public method for the Crystal Report Form, something like:
           public void SetSelection (string firstName, string lastName)
and in it set the SelectionFormula property of the ReportViewer.
You need to parse the string from the ComboBox on the main form before calling SetSelection of the
Report form.
I’ll give some hints on the next page, after a sample picture – but try without looking at the hints!
Form Activated method of the main form:
          int num = contactDataSet.Contacts.Count;
          for ( int i = 0; i < num; i++ )
             contactComboBox.Items.Add( contactDataSet.Contacts[i].Last_Name
                + ", " + contactDataSet.Contacts[i].First_Name );
          contactComboBox.SelectedIndex = 0;

Button Click handler of main form:
          // Assume items are in the ComboBox as:
          //   lastName <comma space> firstName
          ContactReportForm cfr = new ContactReportForm();
          string name = contactComboBox.SelectedItem.ToString();
          int commaIndex = name.IndexOf(',');
          string lastName = name.Substring(0, commaIndex);
          string firstName = name.Substring(commaIndex + 2);
          cfr.SetSelection(firstName, lastName);

Set Selection method to add to the Crystal Report Viewer form:
       public void SetSelection ( string firstName, string lastName )
          crystalReportViewer1.SelectionFormula =
                         "{Contacts.Last Name} = \"" + lastName
                + "\" and {Contacts.First Name} = \"" + firstName + "\"" ;

   To get at components installed on your computer
       o Tools / Customize Toolbox : Select component to be put in the toolbox
   To make your own components
       o File/New/Project – Windows Control Library
       o Here’s where you will often make use of Properties, Events, Exceptions, etc!
       o Library can contain one or more controls
       o Work on a little user control form, similar to the other forms you worked on
       o Can’t run it directly, so
                 Do file / Add Project / New Project / Windows Application as “test bed” main
                 Put your compiled component on the form (It should be in the toolbox)
                 Set it as the Start Up project (under the Project menu item)

   Use a Graphics class instance to draw on
   In a “Paint” method handler, get at a Graphics instance as: Graphics g = e.Graphics;
   There are lots of nice methods to draw lines, rectangles, ellipses, text, etc.
   You can also make Pen objects, Font objects, Brush objects, etc.
   To have the paint method called in your code: Refresh()

Handle Mouse Events
   For MouseUp and MouseDown, get at X, Y position as: e.X, e.Y

Unsafe Code
   Can use C and C++ pointers, pointer arithmetic, address operator, etc.
   Must designate code as unsafe, e.g.: private unsafe void DisplayBitValue() { . . . }
   Must turn on compiler option to allow unsafe code
       o Solution Explorer, right click on project
       o Configuration Properties/Build
       o Set Allow unsafe code to true

Some new C# statements
 foreach: foreach( type identifier in expression ) statement
      o The type and identifier declare the iteration variable of the statement
      o The iteration variable is a read-only local variable with a scope limited to the statement
      o The type of the expression must be a collection type
      o foreach ( int val in myArray ) { Console.WriteLine(val); }

   checked and unchecked: check { . . . }                      unchecked { . . . }
       o Control overflow checking for integer arithmetic

 lock: lock ( reference_type_expression ) statement
     o Obtains mutual-exclusion lock for an object, executes a statement, then releases the lock

   using: using ( resource-acquisition ) statement
       o Obtains one or more resources, executes a statement, and then disposes of the resource
Exercise 9

Make a component that allows a user to set bits and display the value of the bits as Hex, Unsigned
Integer, Signed Integer, or Float.

Below is the component when it is put on the form: “Test Bit Control”

   1. The TextBox that contains the values of the bits should be read only.

   2. The ComboBox should be a DropDownList and should contain the Items:
            Hex Number, Signed Integer, Unsigned Integer, Float

   3. The grid as well as the numbers above it and in it, should be drawn using a graphics reference
      (in the paint event handler).

   4. Clicking on a bit should flip the bit. Use either the mouse up or mouse down event (depending
      on how you want it to behave) and check to see if the mouse position is within a cell

   5. Use constants for the number of bits, cell size, and offset position of the grid. Changing any of
      these (except NUMBITS) should not require any other changes for the component to be

              const   int   NUMBITS = 32;
              const   int   XOFFSET = 10;          // X value start of bit grid
              const   int   YOFFSET = 60;          // Y value start of bit grid
              const   int   CELLSIZE = 24;         // Cell size of bit grid

   6. Fix the width of the component, so it can’t be changed (set Width in paint handler)

   7. Remember to make a project with which to test the component.

On the next page are some code fragments of the way I did this, which you can look at if you get stuck.

Assume:           private uint[] bits = new uint[NUMBITS];                // I could have used byte

To display the value of the bits in the TextBox:

       private unsafe void DisplayBitValue()
          uint val = 0;
          for( int i = 0; i < NUMBITS; i++ )
             val = val | ( bits[i] << i );

           int* ip;
           float* fp;

           switch ( displayAsComboBox .SelectedIndex )
              case 0 :    // Hex Number
                 bitValTextBox.Text = val.ToString("X");
              case 1 : // Signed Integer
                 ip = (int*)&val;
                 bitValTextBox.Text = (*ip).ToString();
              case 2 : // Unsigned Integer
                 bitValTextBox.Text = val.ToString();
              case 3 : // Float
                 fp = (float*)&val;
                 bitValTextBox.Text = (*fp).ToString();

In the constructor:
           displayAsComboBox.SelectedIndex = 0;

Make a Text Changed handler for the ComboBox and put in:             DisplayBitValue();

In the Mouse Up or Mouse Down handler:

           if( e.X > XOFFSET && e.X < (XOFFSET + CELLSIZE * NUMBITS) &&
               e.Y > YOFFSET && e.Y < YOFFSET + CELLSIZE )
              int cellNum = NUMBITS - ((e.X - XOFFSET) / CELLSIZE) - 1;
              if ( cellNum >= 0 && cellNum < NUMBITS )
                 bits[cellNum] = 1 - bits[cellNum];    // flip the bit

The paint handler is on the next page – try not to peek!
Some of the “harder” calculations are to try to get things centered nicely.

Paint Handler:

          // Set the width of the component - don't allow user to set it
          Width = 2 * XOFFSET + NUMBITS * CELLSIZE + 1;

          Pen pen = new Pen(Color.Black);
          pen.Width = 2;
          Font font = new Font("Microsoft Sans Serif", 8.25f);
          Brush brush = new SolidBrush(Color.Black);

          Graphics g = e.Graphics;

          // Draw the grid
          g.DrawRectangle(pen, XOFFSET, YOFFSET, NUMBITS * CELLSIZE, CELLSIZE);
          for ( int i = 1; i < NUMBITS; i++ )
             g.DrawLine(pen, XOFFSET + i * CELLSIZE, YOFFSET,
                             XOFFSET + i * CELLSIZE, YOFFSET + CELLSIZE);

          int labelYPos = YOFFSET - font.Height;
          int valueYPos = YOFFSET + (CELLSIZE - font.Height) / 2;
          for ( int i = 0; i < NUMBITS; i++ )
             // Put on the label
             String cellLabelString = (NUMBITS - i - 1).ToString();
             int xCenterAmount = (int)
                ((CELLSIZE - g.MeasureString(cellLabelString, font).Width) / 2.0 );
             g.DrawString( cellLabelString, font, brush,
                           XOFFSET + i * CELLSIZE + xCenterAmount, labelYPos );

                 // Put the bit values in the cells
                 String cellValueString = bits[NUMBITS - i - 1].ToString();
                 xCenterAmount = (int)
                    ((CELLSIZE - g.MeasureString(cellValueString, font).Width) / 2.0 );
                 g.DrawString( cellValueString, font, brush,
                               XOFFSET + i * CELLSIZE + xCenterAmount, valueYPos );


Documentation Comments:
   Document code using a special comment syntax that contains XML text
   Single-line comments of the form ///… or delimited comments of the form /** … */
   They must immediately precede a user-defined type (such as a class, delegate, or interface) or a
    member (such as a field, event, property, or method) that they annotate

 * <remarks>Class <c>Point</c> models a point in a two-dimensional
 * plane.</remarks>
public class Point
     /// <remarks>method <c>draw</c> renders the point.</remarks>
     void draw() {…}

The following tags provide commonly used functionality in user documentation.
          Tag                                  Purpose
    <c>               Set text in a code-like font
    <code>            Set one or more lines of source code or program output
    <example>         Indicate an example
    <exception>       Identifies the exceptions a method can throw
    <list>            Create a list or table
    <para>            Permit structure to be added to text
    <param>           Describe a parameter for a method or constructor
    <paramref>        Identify that a word is a parameter name
    <permission>      Document the security accessibility of a member
    <remarks>         Describe a type
    <returns>         Describe the return value of a method
    <see>             Specify a link
    <seealso>         Generate a See Also entry
    <summary>         Describe a member of a type
    <value>           Describe a property

   New Project / Setup and Deployment Projects / Setup Project
      o Installer for a Windows Application
      o Can make a new project or add it to an existing project
      o Special file locations are logical names rather than actual names
      o You can add a project output to a folder
      o Lots of other options

Attributes: I’ll leave that for you to look into!


Shared By: