Windows Programming
Windows Programming
Delegate is a type which holds the method(s) reference in an object. It is also referred to as a type safe
function pointer. Delegates are roughly similar to function pointers in C++; however, delegates are type-safe and
secure. A delegate instance encapsulates a static or an instance method and calls the method for execution.
Effective use of delegate improves the performance of applications.
Methods can be called in 2 different ways in C#, those are:
1. Using object of a class if it is not static and name of the class if it is static.
2. Using a delegate (either static or non-static).
To use a delegate for calling a method we need to adopt the following process:
1. Declaration of a delegate.
2. Instantiate the delegate.
3. Using the delegate and calling the method.
Declaration of a Delegate:
[<modifiers>] delegate void|type Name( [<param definitions>] )
Note: while declaring a delegate you should follow the same syntax as in the method i.e. IO parameters of
delegate should be same as the IO parameters of method we want to call using the delegate.
public void AddNums(int x, int y) {
Console.WriteLine(x + y);
}
public delegate void AddDel(int x, int y);
public static string SayHello(string name) {
return Hello + name;
}
public delegate string SayDel(string name);
Instantiate the delegate: In this process we bind the method with delegate, as following:
AddDel ad = new AddDel(AddNums);
or
AddDel ad = AddNums;
SayDel sd = new SayDel(SayHello);
or
SayDel sd = SayHello;
Using the delegate and calling the method: now when we call the delegate by passing the required parameters
values, the method which is bound with the delegate gets executed.
ad(100, 50);
sd(Raju);
Note: Delegates can be defined either with in a class or under a namespace also just like we define other types.
Add a new code file under the project naming it as Delegates.cs and write the following code:
using System;
namespace OOPSProject {
public delegate void AddDel(int a, int b, int c);
public delegate string SayDel(string name);
public delegate void MathDel(int x, int y);
}
Add a new class DelDemo.cs under the project and write the following code:
class DelDemo {
public void AddNums(int x, int y, int z) {
Console.WriteLine(x + y + z);
}
public static string SayHello(string name) {
return "Hello " + name;
}
static void Main() {
DelDemo obj = new DelDemo(); AddDel ad = obj.AddNums; SayDel sd = SayHello;
ad(100, 50, 25); ad(123, 456, 789); ad(396, 224, 156);
Console.WriteLine(sd("Raju")); Console.WriteLine(sd("Naresh")); Console.WriteLine(sd("Praveen"));
Console.ReadLine();
}
}
Multicast Delegate: It is a delegate which holds the reference of more than one method. Multicast delegates must
contain only methods that return void. If we want to call multiple methods using a single delegate all the methods
should have the same IO Parameters. To test this, add a new class MultiDelDemo.cs under the project and write
the following code:
class MultiDelDemo {
public void Add(int x, int y) {
Console.WriteLine("Add: " + (x + y));
}
public void Sub(int x, int y) {
Console.WriteLine("Sub: " + (x - y));
}
public void Mul(int x, int y) {
Console.WriteLine("Mul: " + (x * y));
}
public void Div(int x, int y) {
Console.WriteLine("Div: " + (x / y));
}
static void Main() {
MultiDelDemo obj = new MultiDelDemo(); MathDel md = obj.Add; md += obj.Sub; md += obj.Mul; md += obj.Div;
md(100, 50); Console.WriteLine(); md(575, 25); Console.WriteLine();
md -= obj.Mul; md(678, 28); Console.ReadLine();
}
}
Anonymous Methods:
In versions of C# before 2.0, the only way to declare a delegate was to use named methods. C# 2.0
introduced anonymous methods which provide a technique to pass a code block as a delegate parameter.
Anonymous methods are basically methods without a name, just the body. An anonymous method is inline
unnamed method in the code. It is created using the delegate keyword and doesnt require name and return type.
Hence we can say an anonymous method has only body without name, optional parameters and return type. An
anonymous method behaves like a regular method and allows us to write inline code in place of explicitly named
methods. To test this, add a new class AnonymousMethod.cs and write the following code:
class AnonymousMethod {
static void Main() {
SayDel sd = delegate(string name) {
return "Hello Mr. " + name + " have a nice day.";
};
Console.WriteLine(sd("Raju")); Console.WriteLine(sd("Naresh")); Console.WriteLine(sd("Praveen"));
Console.ReadLine();
}
}
Lambda Expression:
While Anonymous Methods were a new feature in 2.0, Lambda Expressions are simply an improvement to
syntax when using Anonymous Methods introduced in C# 3.0. Lambda Operator => was introduced so that there is
no longer a need to use the delegate keyword, or provide the type of the parameter. The type can usually be
inferred by compiler from usage. To test this, add a new class LambdaExpression.cs and write the following code:
class LambdaExpression {
static void Main() {
SayDel sd = name => {
return "Hello Mr. " + name + " have a nice day.";
};
Console.WriteLine(sd("Raju")); Console.WriteLine(sd("Naresh")); Console.WriteLine(sd("Praveen"));
Console.ReadLine();
}
}
Syntax of defining Lambda Expression: [(] Parameters [)] => { Executed Code }
Why would we need to write a method without a name is convenience i.e. it's a shorthand that allows you
to write a method in the same place you are going to use it. Especially useful in places where a method is being
used only once and the method definition are short. It saves you the effort of declaring and writing a separate
method to the containing class. Benefits are like Reduced typing, i.e. no need to specify the name of the method,
its return type, and its access modifier as well as when reading the code you don't need to look elsewhere for the
method's definition. Lambda expressions should be short. A complex definition makes calling code difficult to read.
Partial Classes (Introduced in CSharp 2.0):
It is possible to split the definition of a class or a struct, an interface over two or more source files. Each
source file contains a section of the type definition, and all parts are combined when the application is compiled.
There are several situations when splitting a class definition is desirable like:
When working on large projects, spreading a class over separate files enables multiple programmers to
work on it at the same time.
When working with automatically generated source, code can be added to the class without having to
recreate the source file. Visual Studio uses this approach when it creates Windows Forms, Web service
Wrapper Code, and so on.
The partial keyword indicates that other parts of the class, struct, or interface can be defined in the
namespace. All the parts must use the partial keyword. All the parts must be available at compile time to form the
final type. All the parts must have the same accessibility, such as public or internal. If any part is declared abstract,
then the whole type is considered abstract. If any part is declared sealed, then the whole type is considered sealed.
If any part declares a base type, then the whole type inherits that class. Parts can specify different base interfaces,
and the final type implements all the interfaces listed by all the partial declarations. Any class, struct, or interface
members declared in a partial definition are available to all the other parts. The final type is the combination of all
the parts at compile time.
Note: The partial modifier is not available on delegate or enumeration declarations.
Add 2 new code files under the project Part1.cs and Part2.cs and write the following code:
using System;
namespace OOPSProject {
partial class Parts {
public void Method1() {
Console.WriteLine("Method 1");
}
public void Method2() {
Console.WriteLine("Method 2");
}
}
}
using System;
namespace OOPSProject {
partial class Parts {
public void Method3() {
Console.WriteLine("Method 3");
}
public void Method4() {
Console.WriteLine("Method 4");
}
}
}
Add a new class TestParts.cs under the project and write the following code:
class TestParts {
static void Main() {
Parts p = new Parts();
p.Method1(); p.Method2(); p.Method3(); p.Method4();
Console.ReadLine();
}
}
Partial Methods(Introduced in C# 3.0): A partial class or struct may contain a partial method. One part of the class
contains the signature of the method. An optional implementation may be defined in the same part or another
part. If the implementation is not supplied, then the method and all calls to the method are removed at compile
time.
Partial methods enable the implementer of one part of a class to define a method and the implementer of
the other part of the class can decide whether to implement the method or not. If the method is not implemented,
then the compiler removes the method signature and all calls to the method. The calls to the method, including
any results that would occur from evaluation of arguments in the calls, have no effect at run time. Therefore, any
code in the partial class can freely use a partial method, even if the implementation is not supplied. No compiletime or run-time errors will result if the method is called but not implemented.
Partial methods are especially useful as a way to customize generated code. They allow for a method
name and signature to be reserved, so that generated code can call the method but the developer can decide
whether to implement the method or not.
A partial method declaration consists of two parts: the definition, and the implementation. These may be
in separate parts of a partial class, or in the same part. If there is no implementation for the declaration, then the
compiler optimizes away both the defining declaration and all calls to the method.
partial void TestMethod();
// Definition in file1.cs
partial void TestMethod() {
// Implementation in file2.cs
// method body
}
There are several rules to follow with partial class and there are several rules to follow with partial method as
defined by Microsoft. Those rules are listed below:
Partial methods are indicated by the partial modifier and can be declared within partial classes only.
Partial methods must be private and must return void.
Partial methods do not always have an implementation and can also be declared as static.
Partial methods can have arguments including ref but not out.
You cannot make a delegate to a partial method.
Add 2 new code files Test1.cs and Test2.cs and write the following code:
using System;
namespace OOPSProject {
partial class Test {
partial void Method1();
public void Method2() {
Console.WriteLine("Method 2.");
}
}
}
using System;
namespace OOPSProject {
partial class Test {
partial void Method1() {
Console.WriteLine("Method 1.");
}
public void Method3() {
Console.WriteLine("Method 3.");
}
static void Main() {
Test obj = new Test();
obj.Method1(); obj.Method2; obj.Method3(); Console.ReadLine();
}
}
}
Windows Programming
In development of any application we need a user interface (UI) to communicate with end users. User
interfaces are of 2 types:
1. CUI (Character User Interface)
2. GUI (Graphical User Interface)
Initially we have only CUI, E.g.: Dos, Unix OS etc., where these applications suffers from few criticisms like:
1. They are not user friendly, because we need to learn the commands first to use them.
2. They do not allow navigating from one place to other.
To solve the above problems, in early 90's GUI applications are introduced by Microsoft with its Windows OS,
which has a beautiful feature known as 'Look and Feel'. To develop GUI's Microsoft has provided a language also in
90's only i.e. VB (Visual Basic), later when .Net was introduced the support for GUI has been given in all languages
of .Net.
Developing Graphical User Interfaces:
To develop GUIs we need some special components known as controls and those controls are readily
available in .Net language's as classes under the namespace System.Windows.Forms. All the control classes that
are present under this namespace were grouped into different categories like:
Common Controls
Container Controls
Menus and Tool Bar Controls
Data Controls
Components
Printing Controls
Dialog Controls
Reporting Controls
Properties, Methods and Events:
Whatever the control it was every control has 3 things in common like properties, methods and events.
1. Properties: these are attributes of a control which have their impact on look of the control.
E.g.: Width, Height, BackColor, ForeColor, etc.
2. Methods: these are actions performed by a control.
E.g.: Clear(), Focus(), Close(), etc.
3. Events: these are time periods which specify when an action has to be performed.
E.g.: Click, Load, KeyPress, MouseOver, etc.
Note: the parent class for all the control classes is the class "Control", which is defined with the properties,
methods and events that are common for each control like Button, TextBox, Form, Panel, etc.
How to develop a Desktop Application (GUI) ?
To develop a Desktop Application (GUI) the base control that has to be created first is Form. To create the
Form first, define a class inheriting from the pre-defined class "Form" so that the new class also becomes a Form.
E.g.:
public class Form1 : Form
To run the Form we have created call the static method Run of Application class by passing the object of
Form we have created as a parameter.
E.g:
Form1 f = new Form1(); Application.Run(f); or Application.Run(new Form1());
Note: we can develop a windows application either by using a notepad following the above process as well as
under visual studio also using "Windows Forms Application" project template.
Developing Windows Application using Notepad: Open notepad, write the following code in it, save, compile and
then execute.
using System; using System.Windows.Forms;
public class Form1 : Form {
static void Main() {
Form1 f = new Form1();
Application.Run(f);
}
}
Developing Windows Applications using Visual Studio:
To develop a windows application under VS open the new project window, select "Windows Forms
Application" project template and specify a name to the project, e.g.: WindowsProject.
By default the project comes with 2 classes in it:
Form1
Program
Form1 is the class which is defined inheriting from predefined class Form, e.g.: public partial class Form1 : Form
Here the class Form1 is partial which means it is defined on multiple files:
Form1.cs
Form1.Designer.cs
Note: we will not find the Form1.Designer.cs file open by default to open it go to solution explorer expand the
node Form1.cs and under it we find Form1.Designer.cs file, double click on it to open.
Program is a static class and in this class we find a Main method under which object of class Form1 is
created for execution, as following:
Application.Run(new Form1());
Note: Program class is the main entry point of the project from where the execution starts.
Windows applications developed under VS have 2 places to work with:
Design View
Code View
Design View is the place where we design the application; this is accessible both to programmers and end
user's whereas Code View is the place where we write code for the execution of application, this is accessible only
to programmers.
Note: because of the design view what VS provides we call it as WYSIWYG IDE (What You See Is What You Get).
Adding new Forms in the project:
A project can contain any no. of forms in it, to add a new form under our project i.e. 'WindowsProject',
open Solution Explorer -> right click on project and select Add -> "Windows Form", which adds a new form
Form2.cs. To run the new form, go to Program class and change the code under Application.Run method as Form2.
E.g.: Application.Run(new Form2());
Properties: as we are aware that every control has properties, methods and events, to access the properties of a
control VS provides 'Property Window' that lists all the properties of a control, to open Property Window select the
control and press F4. We can change any property value in the list of properties, under property window like
Width, Height, BackColor, Font, ForeColor etc., for which we can see the impact immediately after changing the
property value. To test this go to properties of Form2 we have added right now and change any property value you
want.
Whenever we set a value to any property of a control under property window, VS on behalf of us writes
all the necessary code by assigning values to the properties we have modified. We can view that code under
InitializeComponent() method of the class which is called in the constructor of the class. To view code under
InitializeComponent method, go to Code View and right click on the method called in constructor and select 'Go to
definition', this takes us to Form2.Designer.cs file and here also we find the same class Form2 because it is partial.
Setting properties to control manually by writing the code in Notepad:
using System; using System.Drawing; using System.Windows.Forms;
public class Form2 : Form {
public Form2() {
InitializeComponent();
}
private void InitializeComponent() {
this.Text = "My Form"; this.BackColor = Color.Pink; this.Size = new Size(400, 400);
}
static void Main() {
Application.Run(new Form2());
}
}
Events: it is a time period which tells when an action has to be performed i.e. when exactly we want to execute a
method. Every control will have no. of events under it where each event occurs on a particular time period. We
can access the events of a control also under property window only. To view them in the property window choose
events Tab on top of the property window. If we want to write any code that should execute when an event occurs
double click on the desired event corresponding to a control, which takes you to code view and provides a method
for writing the code.
Now in our project add a new form Form3.cs, go to its Events, double click on Load Event and write the
following code under Form3_Load method that is generated in Code View:
MessageBox.Show("Welcome to windows applications.");
Again go to design view, double click on the Click Event and write following code under Form3_Click
method:
MessageBox.Show("You have clicked on form.");
What happens when we double click on an event of a control in the property window?
When we double click on an event in property window internally a method gets generated for writing the
code and that method has a special name "Event Procedure", which is a block of code that is bound with an event
of control and gets executed whenever the event occurs. The code written under event procedure will be executed
by the event whenever the event occurs by taking the help of a delegate internally, as following:
In the above case whenever the Event occur it will call the delegate which then executes the event
procedure that is bound with the event, because a delegate is responsible for execution of the event procedure
first the event, delegate and event procedure should be bound with each other as following:
Syntax:
<control>.<event> += new <delegate> (<event procedure>)
E.g.:
this.Load += new EventHandler(Form3_Load);
button1.Click += new EventHandler(button1_Click);
textBox1.KeyPress += new KeyPressEventHandler(textBox1_KeyPress);
Events and Delegates are pre-defined under BCL (Events are defined in control classes and delegates are
defined under namespaces), what is defined here is only an event procedure. After defining the event procedure in
form class VS links the Event, Delegate and Event Procedure with each other as we have seen above and this can
be found under the method InitializeComponent.
Note: 1 delegate can be used by multiple events to execute event procedures, but all events will not use the same
delegates, where different events may use different delegates to execute event procedures.
How to define an Event Procedure manually?
To define Event Procedures manually we need to follow a standard format as following:
Syntax:
[<modifiers>] void <Name>(object sender, EventArgs e) {
<Stmts>;
}
Event Procedures are non-value returning methods.
An event procedure can have any name but VS adopts a convention while naming them i.e.: <control
name>_<event>. E.g.: Form1_Load, button1_Click, textBox1_KeyPress.
Every event procedure will take 2 mandatory parameters:
i.
Object sender
ii.
EventArgs e
Note: When we define event procedures manually we can give any name to them as per our choice.
Defining Event Procedures in Notepad:
using System; using System.Windows.Forms;
public class Form3 : Form {
public Form3() {
InitializeComponent();
}
private void InitializeComponent() {
this.Text = "My New Form";
this.Load += new EventHandler(TestProc1); this.Click += new EventHandler(TestProc2);
}
private void TestProc1(object sender,EventArgs e) {
MessageBox.Show("Load Event Occured.");
}
private void TestProc2(object sender,EventArgs e) {
MessageBox.Show("Click Event Occured.");
}
static void Main() {
Application.Run(new Form3());
}
}
10
11
Binding an event procedure with multiple controls and identifying Type of control which is raising the event:
Add a new form in the project i.e. Form6 and design it same as Form5. Now double click on button1 which
generates a click event procedure for button1, bind that event procedure with button2, textBox1, textBox2 and
Form6 also and write the following code under the event procedure:
if (sender.GetType().Name == "Button")
MessageBox.Show("Button is clicked.");
else if (sender.GetType().Name == "TextBox")
MessageBox.Show("TextBox is clicked.");
else
MessageBox.Show("Form6 is clicked.");
When an event procedure is bound with multiple controls, any of the control can raise the event in
runtime and executes the event procedure, but the object of control which is raising the event will be coming into
the event procedure and captured under the parameter "sender" of event procedure as following:
As sender is of type object it's capable of storing object or instance of any class in it, so after the object or
instance of the control class is captured under sender by calling GetType() method on it we can identify the type of
control to which that object or instance belongs as we have performed above.
Binding an event procedure with multiple controls and identifying the exact control which is raising the event:
Add a new form in the project i.e. Form7 and design it same as Form5. Now double click on button1 which
generates a click event procedure for button1, bind that event procedure with button2, textBox1, textBox2 and
Form7 also and write the following code under the event procedure:
if (sender.GetType().Name == "Button") {
Button b = sender as Button;
if (b.Name == "button1")
MessageBox.Show("Button1 is clicked");
else
MessageBox.Show("Button2 is clicked");
}
12
13
GroupBox
GroupBox
Change the name of Name TextBox as txtName, Total Fees TextBox as txtFees, Reset Form Button as
btnReset and Close Form button as btnClose.
Change the ReadOnly property of Total Fees TextBox as true so that it becomes non editable, enter 0 as
a value in Text property and also set the TextAlign property as right.
Set the Tag property for each CheckBox and RadioButton with their corresponding fees values and it
should be 0 for Normal RadioButton. Tag property is used for associating user defined data to any
control just like Text property, but Text value is visible to end user and Tag value is not visible to end user.
Click on any one CheckBox so that CheckedChanged Event procedure gets generated; bind that event
procedure with all the remaining CheckBoxs.
Click on any one RadioButton so that CheckedChanged Event procedure gets generated; bind that event
procedure with all the remaining RadioButtons.
Now go to Code View and write the following code.
Class Declarations: int count = 0;
Code under CheckedChanged Event Procedure of all CheckBoxs:
radioButton1.Checked = true;
int amt = int.Parse(txtFees.Text);
CheckBox cb = sender as CheckBox;
if (cb.Checked) {
count += 1; amt += Convert.ToInt32(cb.Tag);
}
else {
count -= 1; amt -= Convert.ToInt32(cb.Tag);
}
txtFees.Text = amt.ToString();
14
15
16
When we set CausesValidation = false for TextBox it will restrict validating event of the control not to
occur so that focus leaves the textbox and form gets closed.
If we want the Phone No TextBox to accept only numeric values and back spaces define a KeyPress event
procedure for Phone No TextBox and write following code in it:
if (char.IsDigit(e.KeyChar) == false && Convert.ToInt32(e.KeyChar) != 8) {
MessageBox.Show("Enter numerics only"); e.Handled = true;
}
KeyPress event occurs when we press and release a key while the focus is in the control.
KeyChar property of KeyPress gets the key value corresponding to the key pressed.
Handled property when set as true will restrict the key value to enter into the control.
Char.IsDigit(char) will return true if the given char is a numeric or else returns false.
Convert.ToInt32(char) will return ascii value of the given character.
Code under Save Button Click Event Procedure: MessageBox.Show("Data saved to database");
Code under Clear Button:
foreach(Control ctrl in this.Controls) {
if(ctrl.GetType().Name == "TextBox") {
TextBox tb = ctrl as TextBox; tb.Clear();
}
}
btnSave.Enabled = false; txtName.Focus();
AcceptButton and CancelButton Properties of the Form Control:
Under Form we have 2 properties AcceptButton and CancelButton which allows us to map buttons on a
form with keyboard keys. AcceptButton property if bound with a button that button gets clicked whenever we
press Enter key of key board. CancelButton property if bound with a button that button gets clicked whenever we
press Esc key of key board. To set them go to properties of form select either AcceptButton or CancelButton
properties which will display the list of buttons on form select a button from them.
ComboBox, ListBox, CheckedListBox:
These controls are also used for providing users with a list of values to choose from, ComboBox allows
only single selection but it is editable which gives a chance to either select from the list of values available or enter
a new value, its a combination of 2 controls DropDownList + TextBox. CheckedListBox by default allows multiselection. ListBox by default allows single selection only but can be changed to multi-selection by setting the
SelectionMode property either to MultiSimple [Mouse Click] or MultiExtended [Ctrl + Mouse Click], default is one.
Adding values to the controls: we can add values to the 3 controls in different ways like:
1. In the properties of the control we find a property Items, select it and click on the button beside it which
opens a window, enter the values we want to add, but each in a new line.
2. By using Items.Add method of the control we can add values, but only one at a time.
<control>.Items.Add(object value)
3. By using Items.AddRange method of the control an array of values can be added at a time.
<control>.Items.AddRange(object[] values)
4. By using DataSource property of the control a DataTable can be bound to it so that all the records of table
gets bound to the control, but as it can display only a single column we need to specify the column to be
displayed using the DisplayMember property.
<control>.DataSource = <data table>
<control>.DisplayMember = <col name>
17
Identifying selected values from the controls: to identify the selected values from the controls we can make use of
the following properties:
ComboBox:
Text -> string
SelectedItem -> object
SelectedIndex -> int
ListBox: SelectedItem -> object
SelectedIndex -> int
SelectedItems -> object[]
SelectedIndices -> int[]
CheckedListBox:
CheckedItems -> object[]
CheckedIndices -> int[]
Add a new form in the project and design it as below, then go to Items property of the ComboBox control,
click on the button beside it and enter a list of countries in the window opened.
SelectedIndexChanged: it is the default event of all the above 3 controls which gets raised once a values is
selected in the list, to test this add a new form in the project, design it as below and add the values Quarter1,
Quarter2, Quarter3 and Quarter4 under the first ComboBox by using its items property and write the code.
18
Declarations:
string[] q1 = { "January", "February", "March" };
string[] q3 = { "July", "August", "September" };
Picture Box
19
20
Members of Timer:
1. Tick: it is an event which occurs whenever the specified interval time elapses.
2. Interval: it is a property using which we specify the frequency of execution in milliseconds.
3. Start(): it is a method to start the execution of timer.
4. Stop(): it is a method to stop the execution of timer.
Developing an Image Viewer Application:
Add a new form in the project. Place a panel control on the form and set the dock property as right. Place
a picture box control on the form and set its dock property as fill and size mode property as StretchImage. Now
design the panel present on the right hand side of the form as following:
List Box
Panel
Name the buttons as btnLoad, btnPrev, btnNext, btnStart and btnStop. Set the Enabled property of
btnPrev, btnNext and btnStart button as false, set the Visible property of btnStop as false, then go to properties of
form and under its CancelButton property select the button as btnStop which gets mapped to Esc key of keyboard.
Add the FolderBrowserDialog and Timer controls to the form, set the Interval property of Timer as 2991 and write
the following code in Code View:
using System.IO;
Declarations: string dirPath; int panelWidth;
Code under Load Images Button Click Event Procedure:
DialogResult dr = folderBrowserDialog1.ShowDialog();
if (dr == DialogResult.OK) {
dirPath = folderBrowserDialog1.SelectedPath; string[] files = Directory.GetFiles(dirPath, "*.jpg");
if(files.Length > 0) {
listBox1.Items.Clear();
foreach (string file in files) {
int pos = file.LastIndexOf("\\"); string fname = file.Substring(pos + 1); listBox1.Items.Add(fname);
}
listBox1.SelectedIndex = 0; btnPrev.Enabled = false; btnNext.Enabled = true; btnStart.Enabled = true;
}
}
Code under ListBox SelectIndexChanged Event Procedure:
string imgPath = listBox1.SelectedItem.ToString(); pictureBox1.ImageLocation = dirPath + "\\" + imgPath;
Code under Start Slide Show Button Click Event Procedure:
panelWidth = panel1.Width; panel1.Width = 0; btnStop.Visible = true; timer1.Start();
Code under Stop Slide Show Button Click Event Procedure:
timer1.Stop(); btnStop.Visible = false; panel1.Width = panelWidth;
Note: write code for << (Previous), >> (Next) buttons for navigating to next and previous images as well as write
code under the Timer Tick event for playing the slide show of images.
Adding Menu's to a Form:
To add menu's to Form first we need to place a MenuStrip control on the Form which is present under
Menu's and Toolbars Tab of Toolbox, which sits on top of the Form as the dock property is set as Top.
To add a Menu on MenuStrip click on LHS corner of it which shows a textbox asking to Type Here, enter
Text in it which adds a Menu, and repeat the same process for adding of multiple Menu's.
21
To add a MenuItem under a menu, click on the Menu which shows a textbox below asking to Type Here,
enter Text in it which adds a MenuItem, and repeat the same process for adding of multiple MenuItems.
Note: both Menu and MenuItem are objects of the class ToolStripMenuItem.
If we want Menu's to be responding for "Alt Keys" of keyboard prefix with "&" before the character that
should respond for Alt.
E.g.: &File &Edit F&ormat
To define a shortcut for MenuItems so that they respond to keyboard actions, go to properties of
MenuItem, select Shortcut Keys Property, click on drop down beside it, which displays a window, in that window
choose a modifier Ctrl or Alt or Shift and then choose a Key from ComboBox below.
To group related MenuItems under a Menu we can add Separators between MenuItems, to do it right
click on a MenuItem and select Insert -> separator which adds a separator on top of the MenuItem.
Note: same as we inserted a separator we can also insert a MenuItem if required, in the middle.
If we want to display any Image beside MenuItem right click on it and select Set Image which opens a
window, select Local Resource and click on Import button which opens a DialogBox, using it select an image from
your Hard disk.
Sometimes we find check mark beside MenuItem to identify a property is on or off, e.g.: Word Wrap
under Notepad. To provide check marks beside a MenuItem right click on it and select "Checked", but to check or
uncheck the item in run time we need to write code explicitly under click event of MenuItem as following:
if (<control>.Checked == true)
{
<control>.Checked = false;
}
else
{
<control>.Checked = true;
}
Multi Document Interface:
When designing an application it can contain any no. of forms in it, right now to run the desired form we
are explicitly specifying the form class name under Program class. But, when we provide the application to client
we only give him the assemblies of the project (i.e. IL Code) so client doesn't have a chance to edit the class
Program and specify the form class name he wants to run.
To overcome the above problem we are provided with an approach known Multi-Document
Interface, where in this approach an application will be having only one form as a startup Form which is referred as
MDI Parent or MDI Container, so that clients don't require changing the form name under program class at any
time. Rest of the forms in application will be under the control of MDI Parent Form and referred as MDI Child's. To
make a form as MDI Parent set the property IsMdiContainer as true. To launch a form as child of parent create
object of child form class, set its MdiParent property with parent forms reference and then call Show() method.
Note: an application can have only one MDI Parent and all other forms must be children of parent which should
come and sit under parent. E.g.: Visual Studio by default launches as an MDI Container and the all other forms like
New Project and Add New Item windows will come and sit under it as its children.
Layout:
When we have more than one child form opened at a time under parent, child forms will be arranged
inside the parent by using a layout for arrangement, which can be any of the following 4 options like:
I.
Cascade (d): child forms are arranged 1 on the top of the other.
II.
TileVertical: child forms are arranged 1 beside the other.
III.
TileHorizontal: child forms are arranged 1 below the other.
IV.
ArrangeIcons: all child forms icons are arranged with in the bottom of parent.
22
To test this now add a new Form in the Project naming it as MdiParent.cs, set its IsMdiContainer property as
true to make it as a MDI Parent and also set the WindowState property as Maximized so that form gets launched
to the full size of the screen. Add a MenuStrip control to the Form and place 2 menus on it: Forms and Layout.
Under Forms Menu add a MenuItem for each child form to launch e.g.: Form1, Form2, Form3 etc. Under Layout
Menu add the following MenuItems: Arrange Icons, Cascade, Horizontal and Vertical and write the following code:
Code under Each Form's MenuItems:
this.LayoutMdi(MdiLayout.ArrangeIcons);
this.LayoutMdi(MdiLayout.Cascade);
this.LayoutMdi(MdiLayout.TileVertical);
this.LayoutMdi(MdiLayout.TileHorizontal);
RichTextBox:
This control works same as a TextBox but provides advanced text entry and editing features such as
character and paragraph formatting.
Members of RichTextBox Control:
Properties: BackColor, ForeColor, WordWrap, Modified, Font, ScrollBars, SelectedText, SelectionColor etc.
Methods: Cut(), Copy(), Paste(), Undo(), Redo(), Clear(), ClearUndo(), SelectAll(), DeselectAll(), Focus(),
ResetText(), Refresh(), LoadFile(string path, RichTextBoxStreamType fileType), SaveFile(string path,
RichTextBoxStreamType, fileType)
RichTextBoxStreamType is an enum that specifies the types of input and output streams used to load and save
data in the control. The enum provides a list of constants like PlainText, RichText, UnicodePlainText etc.
MaskedTextBox:
This control looks same as a TextBox but can be used for taking the input in specific formats from the
users. To set a format for input, select the Mask property in property window and click on the button beside it
which opens a window, in it we can either choose a mask from list of available masks or select custom and specify
our own mask format using zeros in the mask textbox below as following:
Railway PNR:
000-0000000
CC No.:
0000-0000-0000-0000
Short Date:
00/00/00
User Controls
These are re-usable software components that are developed by application developers to consume
under their applications. We can develop User Controls in 2 ways:
Creating a new control from existing controls.
Inherited or extended controls.
In the first case we design a control making use of existing controls and then write the required behavior
for the control. To design a control first we need to define a class (because every control is a class) inheriting from
the predefined class UserControl which provides a container for designing.
In the second case we don't design anything newly; we only copy the design of an existing control for
adding new functionalities or behavior that is required. In this case we define a class that is inheriting from the
control class for which new behavior has to be added.
To create a control in first process we need to add UserControl Item Template in the project which
provides a class that is inheriting from UserControl class, whereas in the second case we need to add Class Item
Template and then inherit from the control class we want to extend.
23
Note: to develop UserControls we are provided with Windows Forms Control Library project template. But the
controls whatever we develop are finally consumed from Windows Forms Applications only.
People working on controls are classified as:
I.
Component Developers
II.
Application Developers
The person who develops controls is known as component developers and those who consume the
controls are known as application developers or component consumers. While developing controls the developer
should first design the control, write all the behavior to control and then define any required properties, methods
and events for the control.
Properties: these are defined to provide access to any values associated with the control to application developer.
E.g.: Text property of TextBox, Checked property of CheckBox etc.
Methods: these are defined so that any actions can be performed thru the controls whenever required.
E.g.: Clear(), Focus() methods of TextBox, Close() method of Form etc.,
Events: While developing a control the developer of control may not know what actions has to be performed at
some specific time periods. For example:
1.
2.
3.
4.
5.
The developer of button control is not aware what should happen when end user clicks on the button.
What should happen when button is clicked by end user will be decided by the application developer.
Even if decided by application developer it is the responsibility of component developer to execute the
code that is written by application developer whenever end user clicks on the button.
To resolve above problem component developer first defines an event under his control and then asks the
application developer to write code under an event procedure, binding it with the event he has defined,
so that whenever the event occurs or raises event procedure gets executed.
To execute the event procedure we are already aware that events will take the help of delegates.
Note: As we are aware that events take help of delegates to execute event procedures, so while defining events
we must also specify that which delegate will be used by event to execute the event procedure. So first a delegate
has to be defined and then the event has to be defined. For example:
public delegate void EventHandler(object sender, EventArgs e);
public event EventHandler Click;
All delegates that are pre-defined in BCL which we are consuming right now under existing Controls
Events are declared with 2 parameters:
1. object sender
2. EventArgs e
This is the reason why all our event procedures are also taking the same two parameters because we are
already aware that IO parameters of delegate should be same as the IO parameters of method it has to call.
Note: While defining events under user controls we can either make use of any pre-defined delegate or we can
also define our own delegates.
24
Go to properties of MaskedTextBox, set the Mask property by clicking on the button beside the property,
select Time (US), set the text property as 0000 and also set the ReadOnly property as True, then add a Timer
control and set the interval property as 997. Now go to code view and write the following code in the class:
Declarations:
public delegate void MyDelegate();
//Defining a delegate for using it under the event
public event MyDelegate MyClick;
//Defining a MyClick event using the above delegate
int sec, min; string secstr, minstr;
Under Timer Tick Event:
if (sec < 59)
sec += 1;
else {
sec = 0; min += 1;
}
25
}
}
}
}
26
27