Upload
others
View
4
Download
0
Embed Size (px)
Citation preview
Visual C# - Penn P. Wu, PhD. 298
Lecture #10 Hand-Coding Windows Forms Applications
Introduction The .NET Framework provides class-based libraries, such as dialog boxes, menus, buttons, text
boxes, and so on, for developers to create instances of them to build a “Windows forms
applications”. A “framework”, in programming terms, is a collection of application
programming interfaces (APIs). The term “Windows forms” describes refers to the smart client
technology developed by Microsoft for the .NET Framework to provide a set of managed libraries that simplifies interactions between users and the Windows operating systems.
Windows forms applications use a “form” to host graphical user interfaces (GUIs). According
to Microsoft, a “form” is visible, rectangular area that provides a surface to display user
interfaces (UIs) to interface with users. The following figure shows a simple “Windows Forms
application”. The border-defined rectangular area is the “form” which contains a “Label”, a
single-line “TextBox”, a “Button”, and a multi-line “TextBox” as user interfaces.
In a nutshell, programming of a “Windows forms application” is the action that writes codes to:
(1) add “controls” to a form to display data or accept inputs, (2) detect user actions such as
mouse clicking or key pressing, and (3) respond to user requests of interaction such as
displaying results of a calculation. A “control” is a user interface (UI) element that displays
data or accepts data input.
This lecture will guide students through a learning journey to explore how C# developers can
apply skills of object-oriented programming to implement the .NET Framework’s class-based
libraries to hand-code Windows forms applications.
Barebone of a
“form”
The .NET Framework provides the System.Windows.Forms namespace which contains
classes for creating Windows-based applications. Among these classes, the “Form” class
provides the members to create standard, tool, borderless, and floating windows. C# developers
can: (1) declare the use of the “System.Windows.Forms” namespace, (2) define a subclass that
inherits the “Form” class, and (3) then create an instance of the subclass to build the barebone
of a “form”.
Additionally, similar to all other C# application, a Windows forms application also requires the
System namespace because it contains fundamental classes and base classes that define
commonly used value and reference data types, events and event handlers, interfaces,
attributes, and processing exceptions. The following demonstrates how to declare the use of
“System” and “System.Windows.Forms” namespaces.
using System;
using System.Windows.Forms;
The above statements all begin with a using directive followed by the fully qualified names to
specify the hierarchy of namespaces. The main reason to declare the use of these namespaces is
to eliminate the need to use fully qualified names inside the class body. For example, the
“Form” class is a member of the “System.Windows.Forms” namespace. As in any generic C# code, there must be a default class. The following compares a class named “Form1” that
Visual C# - Penn P. Wu, PhD. 299
inherits the “System.Windows.Forms.Form” class with and without the declaration of
namespace using their fully qualified names. It also explains how the above statements can
eliminate the need of fully qualified names.
with using System;
using System.Windows.Forms;
public class Form1 : Form { }
without using System;
public class Form1 : System.Windows.Forms.Form { }
In a nutshell, the using directive gives the “Form1” class the access permission to the
namespace it specifies; therefore, the “Form1” class can use all public members of the
specified namespace. Since the namespace is declared by the using directive, programmers of
the “Form1” class do not have to use the long fully qualified name when referencing any
member of these namespaces.
Throughout this course, students will frequently declare the use of the following namespaces with the using directive.
using System;
using System.Drawing;
using System.Windows.Forms;
The following demonstrates how to create a subclass named “Form1” that inherits the
System.Windows.Forms.Form class. Through the C# style of inheritance, the following
statement enables programmers to create a new class named “Form1” that can immediately
access all public members defined in the System.Windows.Forms.Form class. By the way,
since previous statements have declared the use of the “System.Windows.Forms” namespace,
the fully qualified name “System.Windows.Forms.Form” can be simplified to “Form”.
public class Form1 : Form { }
According the above statement, “Form1” is a subclass of the System.Windows.Forms.Form
class. Since the System.Windows.Forms.Form class provide tools to a standard and floating
Windows “form” and interactive user interfaces like “Button”, “TextBox”, programmers of the
“Form1” class can begin the hand-coding to add all “components” of the Windows “form”.
As a subclass, the custom-made subclass “Form1” can have a default constructor to define
default behaviors and default appearances. By the way, a constructor of a class has the same
identifier as the class. Inside the “Form1” class, programmers can define a default constructor
that must have exactly the same name as the class. This default constructor is typically a zero-
argument constructor that will be automatically called when an instance of the “Form1” class is
instantiated, unless the programmer detours this routine. This default constructor is often used
to set the default values of the form. The following demonstrates how to add a default
constructor within the “Form1” class.
public class Form1 : Form
{
public Form1() { } // default constructor
}
Visual C# - Penn P. Wu, PhD. 300
As discussed in one of the previous lectures, the following is the barebone “template” code for
hand-coding a generic Windows “form”. With only the “template” code, developer can create a
blank Windows “form” application.
using System;
using System.Windows.Forms;
public class Form1 : Form
{
public Form1() { }
[STAThread]
public static void Main()
{
Application.Run(new Form1());
}
}
As a C# application, the “Form1” class (as the class that will be called for execution) needs a
Main() method as its entry point. In C#, the Main() method is optionally (but preferably)
defined in a section specified by the [STAThread] attribute.
[STAThread]
public static void Main()
{
Application.Run(new Form1());
}
When the STAThread attribute is used, it changes the apartment state of the current thread to
be single threaded. The single thread mode ensures the Main() method is the only one on the
communication with the current thread. It blocks other threads that may want to communicate with the Main() via Component Object Model (COM). If this attribute is not present, the
application uses the multithreaded apartment model, which is not supported for Windows
Forms. According to Microsoft,
“Windows Forms is not supported within an MTA or free threaded apartment.
Applications using Windows Forms should always declare the apartment style they're
using, as some other component could initialize the apartment state of thread
improperly.”
Inside the Main() method, programmers call the “Run()” method of the
“System.Windows.Forms.Application” class to begin running a standard application message
loop on the current thread and makes the specified form visible. The “Run()” method takes one
parameter which must be an instance of the “Form1” class. The following illustrates how to
create an anonymous instance of the “Form1” class.
Application.Run(new Form1());
The following demonstrates how to create an identifiable instance of “Form1” named “fm1”. It
also demonstrates how to make “fm1” the parameter of the “Run()” method.
Form1 fm1 = new Form1();
Application.Run(fm1);
The “System.Windows.Forms.Application” class provides static methods and properties to
manage an application, such as methods to start and stop an application, to process Windows
messages, and properties to get information about an application. The Main() method calls
Run() to start the application, which creates the form.
Visual C# - Penn P. Wu, PhD. 301
While the above code provides the core mechanism to build a Windows form, Microsoft
suggests programmers to apply the object-oriented programming paradigm to the coding of
function-rich Windows form applications. In the following example, a private method named
“InitializeComponent()” is used to defined form components (such as button, label, checkbox, and drop-down menu). The only thing the default constructor, Form1(), does is to call the
InitializeComponent() method. This arrangement prevents any external class from
accessing the “InitializeComponent()” method to create a Windows form defined by the “Form1” class.
using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;
namespace Samples
{
public class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void InitializeComponent()
{
// add form components here....
}
}
public class Form2 : Form // external class
{
[STAThread]
public static void Main()
{
Application.Run(new Form1());
}
}
}
In the above code, the “Form2” class is an external class to “Form1”. It can create an instance
of the “Form1” class, but it cannot access the “InitializeComponent()” method.
The System.ComponentModel namespace provides classes that are used to implement the
run-time and design-time behavior of components and controls. This namespace includes the
base classes and interfaces for implementing attributes and type converters, binding to data
sources, and licensing components.
Controls In terms of Windows forms application, a “control” is an interactive user interface within a
Windows form to could either take the inputs or dynamically display outputs. The following
are commonly used controls provided by the “System.Windows.Forms” namespace. They are
components within a Windows form for displaying information or accepting user inputs.
Control Sample UI Descriptions
Checkbox
Allows multiple option
Visual C# - Penn P. Wu, PhD. 302
Radio button
Allow only one option
Button
Clickable button
Textbox
A single line text entry area
ComboBox
A drop down menu
ListBox
An area of list of options
Most controls in .NET Framework derive from the System.Windows.Forms.Control class
which defines the basic functionality of the controls including properties, methods, and events
of the controls. Interestingly, most controls are defined as individual classes under the
System.Windows.Forms namespace. Therefore, each type of control has its very own and
complete set of properties, methods, and events that make the instance of the control suitable for a particular purpose. Programmers can manipulate controls by writing code to add controls
dynamically at run time.
The following illustrates the generic format of syntax to declare and instantiate (create) a
control in C#.
controlName objectName = new controlName();
The following demonstrates how to declare an instance of the “Label” class named “label1”.
System.Windows.Forms.Label label1;
By declaring the use of “System.Windows.Forms” namespace, programmers can eliminate the
need to use fully qualified name of the “Label” class with the using directive of
System.Windows.Forms namespace, as shown below. Throughout this course, the instructor
chooses to use this approach to eliminate the need of fully qualified names.
using System.Windows.Forms;
.............
Label label1;
The instantiation requires the use of the new operator, which instructs the computer to allocate
resources (particularly memory space) to actually create the “Label1” instance (or object) by
invoking the “Label()” constructor of the “Label” class. The “Label()” constructor is the
default constructor of the “Label” class. According to Microsoft, there is not overridden
constructor. Therefore, the “Label()” constructor is the only one that can initialize a new
instance of the “Label” class.
label1 = new Label();
Programmer can choose to declare and instantiate the instance (or object) in one single
statement, depending on the management of “scope”. In programming, the term “scope” refers
to the visibility of an object (such as an instance or a variable). It defines which parts of the
program can see or use the “scope-limited” object. The following demonstrates how to declare
and create an instance in one single statement.
Label label1 = new Label();
Visual C# - Penn P. Wu, PhD. 303
A Label control is typically used to provide descriptive text that can be changed at the runtime
programmatically. For example, you can use a Label to add descriptive text for a TextBox
control to inform the user about the type of data expected in the control. The following further
explain the statement: (1) specifies the class, (2) is the identifier, and (3) is the constructor that actually creates the control. Throughout the entire program life span, “label1” represent this
“Label” control.
Label label1 = new Label();
(1) (2) (3)
Similarly, the following declares and creates a “TextBox” object named “textBox1”. A
“TextBox” control allows users to enter or edit a text or a numeric value as inputs.
TextBox textBox1 = new TextBox();
Additionally, a control must be added to the “form” (which serves as a container) by using the
“Add()” method of the Controls object; otherwise, the control will not be present in the “form”.
In the following example, “this” is a keyword that represents the hosting form.
this.Controls.Add(label1);
If the application contains only one single form, then the “this” keyword may be omitted. The following statement adds label1 to the Form1 Controls collection object with an assumption
that “label1” is added to its hosting form.
Controls.Add(label1);
The following demonstrates how to use the “template” code to create a Windows form application. Then, it declares and creates a lists of controls as private members of the “Form1”
class. Therefore, these controls can be accessed by any other member of the “Form1” class.
public class Form1 : Form
{
//Controls.
private TextBox textBox1 = new TextBox();
private Button button1 = new Button();
private ListBox listBox1 = new ListBox();
private CheckBox checkBox1 = new CheckBox();
private Label label1 = new Label();
..........
..........
//Add controls to the form.
this.Controls.Add(textBox1);
this.Controls.Add(button1);
this.Controls.Add(listBox1);
this.Controls.Add(checkBox1);
this.Controls.Add(label1);
}
The following declares and create these controls within the “Form1()” constructor. They are
scope-limited to the “Form1()” constructors, which means only the “Form1()” constructor can access them.
public class Form1 : Form
{
public Form1()
{
//Controls.
Visual C# - Penn P. Wu, PhD. 304
TextBox txtBox1 = new TextBox();
Button button1 = new Button();
ListBox listBox1 = new ListBox();
CheckBox checkBox1 = new CheckBox();
Label label1 = new Label();
..........
..........
//Add controls to the form.
this.Controls.Add(textBox1);
this.Controls.Add(button1);
this.Controls.Add(listBox1);
this.Controls.Add(checkBox1);
this.Controls.Add(label1);
}
}
The following adds one “Label” control to the “form”. The instructor chooses to declare the
“Label” instance as a member of the “Form1” class; therefore, all parts of the “Form1” class
can access it. The instantiation is done within the “Form1()” constructor. At this moment, the
Label control is not visible because some of its required properties have not yet specified by
the programmer.
using System;
using System.Windows.Forms;
namespace Samples
{
private Label label1; //declare
public class Form1 : Form
{
public Form1()
{
label1 = new Label(); //instantiate
......
this.Controls.Add(label1); //add to the form
}
[STAThread]
public static void Main()
{
Application.Run(new Form1());
}
}
}
Implementation of controls
All classes of Controls are made for programmers to use as APIs (application programming interfaces) through the use of object-oriented programming. To use members of the “Label”
class, for example, programmers must create an instance of the “Label” class (e.g. “label1”).
After instantiation, the “label1” instance can implement all members of the “Label” class. The
following demonstrates how to set the alignment of “label1” by using the “TextAlign” property
of the “Label” class.
label1.TextAlign = ContentAlignment.MiddleCenter
The implementation of Controls objects is centered on four aspects: (1) property, (2) method,
(3) event, and (4) event handler. The .NET Framework provides properties, methods, and events. Programmers use them by learning the usage specified by the .NET Framework (as
Visual C# - Penn P. Wu, PhD. 305
APIs). As to the event handler, the programmers create the code by studying the syntax. The
following depicts these terms.
1. Properties: All controls have several properties that are used to manipulate the behavior
of the control.
2. Methods: Methods are individually functional code blocks with unique identifier to perform a special task. They are defined in the Control classes to be inherited by other
control classes.
3. Events: The term “event” refers to user’s activities such as clicking a button, moving the
cursor, or dragging an object. The Control class defines several events and related
supportive tools to help the programmers detect and respond to these events.
4. Event handler: An event handler is a user-defined function, strictly using the syntax
defined by the .NET Framework, to respond to the raised event.
The following code demonstrates how the “label1” instance implements three different
members of the “Label” class: “Text”, “Location”, and “Size”. Some members of a control
class require an instance of other .Net Framework classes. In order to place the Label in a
relative location (10, 10), it is necessary to create an anonymous instance of the
System.Drawing.Point class by calling the Point() constructor of the System.Drawing.Point
class; therefore, the instructor chooses to declare the use of the System.Drawing namespace.
using System.Drawing;
............
public class Form1 : Form
{
public Form1()
{
Label label1 = new Label();
label1.Text = "Welcome to CIS218 Visual C#!";
label1.Location = new Point(10, 10);
label1.Size = new Size(260, 30);
this.Controls.Add(label1);
}
............
Properties and
methods of a
control
The following is the generic syntax to use a property.
objectID.propertyName = value;
The following demonstrates how to set the content of a Label through the use of “Text”
property. It sets the content of the “label1” object to “Welcome to CIS218!”.
label1.Text = "Welcome to CIS218!";
The following table lists the commonly used properties. They apply to most controls.
Property Description AutoSize Gets or sets a value indicating whether the control is automatically
resized to display its entire contents.
BackColor Gets or sets the background color for the control.
Enabled Gets or sets a value indicating whether the control can respond to user
interaction.
Visual C# - Penn P. Wu, PhD. 306
ForeColor Gets or sets the foreground color of the control.
Height Gets or sets the height of the control.
Location Gets or sets the coordinates of the upper-left corner of the control
relative to the upper-left corner of its container.
Name Gets or sets the name of the control.
Size Gets or sets the height and width of the control.
Text Gets or sets the text associated with this control.
TextAlign Gets or sets the alignment of text in the label.
Visible Gets or sets a value indicating whether the control and all its child
controls are displayed.
Width Gets or sets the width of the control.
Programmers need to visit the https://docs.microsoft.com/en-
us/dotnet/api/system.windows.forms?view=netframework-4.7.2 site to obtain the
details about using the properties and methods of a control.
Values of some properties are not scalar values, they are anonymous instances of a class and
must be initialized with the new operator following by a constructor of some class.
For example, the “Size” property only takes an instance that is instantiated by the Size()
structure. The following sets the size of label1 is set to 267 pixels wide by 40 pixels high.
label1.Size = new Size(267, 40);
Similarly, the “Location” property specifies where the Label is placed on the screen. However,
it only accepts an anonymous instance of the Point() constructor of the System.Drawing
namespace. This Point() constructor is used frequently in Windows Forms applications to
specify X and Y screen coordinates. In the following example, the Location of the label1 is 12
pixels from the left and 56 pixels from the top of the main form. Here is how the Location
property of the label1 label is set:
label1.Location = new Point(12, 56);
In the following example, the “textBox1” control is declared within the “Form1” class but
outside the “Form1()” constructor. However, “textBox1” is instantiated within the “Form1()”
constructor. Its “Location” property is set to be (10, 10) while the “Size” property is set to be
265×50 pixels.
TextBox textBox1;
..........
public Form1()
{
this.Size = new Size (300, 150); //size of the form
textBox1 = new TextBox();
textBox1.Location = new Point(10, 10);
textBox1.Size = new Size(265, 50);
this.Controls.Add(textBox1);
...............
Visual C# - Penn P. Wu, PhD. 307
In the above example, the instructor uses the following statement to set the dimension of the
“form” (which is represented by the “this” keyword) to 300×150 pixels.
this.Size = new Size (300, 150);
All control classes provide a variety of methods to enhance the functionality of the control.
These methods of function of the class and can perform a specific task. The following lists
some common methods that apply to most controls.
Method Description Dispose() Releases all resources used by the Component.
Equals() Determines whether the specified object is equal to the current object.
Hide() Conceals the control from the user.
Invalidate() Invalidates the entire surface of the control and causes the control to be
redrawn.
Refresh() Forces the control to invalidate its client area and immediately redraw
itself and any child controls.
Select() Activates the control.
Show() Displays the control to the user.
The Hide() method conceals the control from the user.
lable1.Hide();
Event and
event handler
of a control
An event is an action performed by a user such clicking a button, pressing a key, or moving the
mouse cursor. Windows forms applications are typically designed as event-driving applications
that have code to respond to an event. The following figure shows a “form” that has a “TextBox” control for inputs, a “Button” control, and two “RadioButton” controls. When a
value is entered to the “TextBox” control, the user “raises” an event. When the “Button”
control is clicked or one of the “RadioButton” is checked, events are raised.
The “Event Model” in the .NET Framework provide a set of “event delegates” with each
connecting to a specific “event”. Programmers must write custom-made methods as the “event
handler” and register the “event” with the “event handler”. By the definition, an “event
handler” is a method that is bound to an event. When the event is raised, the code within the
event handler is executed. The following figure illustrates the sequence.
Visual C# - Penn P. Wu, PhD. 308
The types of events raised by a control object vary while the “Click” event is common to most
controls because most control can handle a “Click” event. The following illustrates the syntax
to register an event in C#, in which controlName is the identifier of instance of a control,
eventNama is the official event name provided by the .NET Framework (e.g. “Click”), “new” is
the keyword that creates an anonymous instance of the “EventHandler” delegate, and the “this”
keyword refers to the current hosting “form”, and methodName is the identifier of a method
that serves as the “event handler”.
controlName.eventName += new EventHandler(this.methodName);
The EventHandler delegate represents a method that will handle an event which has no event
data. In a nutshell, a “delegate” is a class that references to a method which is specified within
a pair of parentheses. Visual Studio adopts an interesting naming convention for the “event
handler”, as explained below.
controlName_eventName()
The following demonstrates how to register a “TextChanged” event to the “textbox1” control
with a “delegate” that represents a custom-made method named “textBox1_TextChanged()”.
TextBox textBox1 = new TextBox();
...........
textBox1.TextChanged += new
EventHandler(this.textBox1_TextChanged);
In the above example, “textBox1” is an instance of the “TextBox” control which supports an event named “TextChanged”. When a user enters or changes the value in a TextBox control
(which will change the value of the “Text” property of the TextBox control), an
“TextChanged” event is raised. Once the “TextChanged” event is raised, the above code
instructs the computer to search for a custom-made method named “textBox1_TextChanged()”.
This method is known as the “event handler” which should contain the instructions as how to
respond to the “TextChanged” event.
As shown in the above figure, an “event” must have an associated “event handler”. The
following is a sample event handler that match with the above event registration. The identifier
(name) of the event handler is “textBox1_TextChanged”.
textBox1.TextChanged += new
EventHandler(this.textBox1_TextChanged);
............
private void textBox1_TextChanged(object sender, EventArgs e)
{
//statements
}
The .NET Framework has a rigid syntax for event handler, as illustrated below. First, it must be
a method that takes two parameters: one is an instance of the “object” class, the other is an
instance of the “EventArgs” class. Microsoft also recommend to name the object “sender” and
the EventArg “e”. Event handlers are typically declared as private because they should not be accessed by any external object.
accessModifer void methodName(object sender, EventArgs e) { }
event
(TextChanged)
event handler
(textBox1_TextChanged()
)
delegate event evetnt handler
Visual C# - Penn P. Wu, PhD. 309
The control that raises the event is called the event sender because it sends a request to the
event handler; therefore, the above syntax chooses to the word “sender” as its identifier. On the
contrary, the event handler plays of the role a “receiver” to receive the call and then respond to
the sender’s request. In the following example, the identifier “sender” is a reference of “textBox1”.
textBox1.TextChanged += new
EventHandler(this.textBox1_TextChanged);
............
private void textBox1_TextChanged(object sender, EventArgs e)
Since the control can be of an instance of any available class (such as “Button”, “Label”, or
“TextBox”, Microsoft suggests declaring it as the System.object type (which is a universal
data type). The instance of System.EventArgs class, “e”, represents the event data generated by the operating systems after the event is raised. All the event arguments are implemented by the
EventArgs class (or a class of similar kind).
The event handler is the one that responds to the event; therefore, its body should contain
instructions of response. In the following example, the event handler will assign whatever the
user enters to “textBox1” as value of the “Text” property of “label1” control.
private void textBox1_TextChanged(object sender, EventArgs e)
{
label1.Text = textBox1.Text;
}
Every control has its default events according to Visual .NET framework. They are defined in
the “System.Windows.Forms.Control” class. Visit the https://docs.microsoft.com/en-
us/dotnet/api/system.windows.forms.control?view=netframework-4.7.2#events site for a
complete list of event names. The table also provides sample names of event handlers.
Control Default event Sample name of event handler
Button Click
button1_Click()
TextBox TextChanged
textBox1_TextChanged()
Label Click
label1_Click()
CheckBox CheckedChanged
checkBox1_CheckedChanged()
GroupBox Enter
groupBox1_Enter()
RadioButton CheckedChanged
radioButton1_CheckedChanged()
PictureBox Click
pictureBox1_Click()
DateTimePicker ValueChanged
dateTimePicker1_ValueChanged()
DataGrid Navigate dataGrid1_Navigate()
The following is a complete sample code that demonstrates how the above discussions work.
The instructor purposely declares “textBox1” and “label1” as members of the “Form1” class;
therefore, they can be accessed by the event handler (the “textBox1_TextChanged()” method) which is an individual method of the “Form1” class.
using System;
using System.Drawing;
Visual C# - Penn P. Wu, PhD. 310
using System.Windows.Forms;
public class Form1 : Form
{
private TextBox textBox1; // member of Form1 class
private Label label1;
public Form1()
{
textBox1 = new TextBox(); //instantiation
textBox1.Size = new Size(260, 25);
textBox1.Location = new Point(10, 10);
textBox1.Multiline = true;
textBox1.TextChanged += new
EventHandler(this.textBox1_TextChanged);
this.Controls.Add(textBox1);
label1 = new Label();
label1.Size = new Size(260, 250);
label1.Location = new Point(10, 50);
this.Controls.Add(label1);
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
label1.Text = textBox1.Text;
}
[STAThread]
public static void Main()
{
Application.Run(new Form1());
}
}
A sample output looks.
In practice, programmers can always develop user-defined function in C# to deliver a special
feature. For example, the instructor creates a new regular C# function named “UpIt()” which
converts the all letters in a string to uppercase. By modifying the textBox1_TextChanged()
event handler, every letter typed into the textbox will be forced to displayed in uppercase.
private void textBox1_TextChanged(object sender, EventArgs e)
{
label1.Text = UpIt(textBox1.Text);
}
Visual C# - Penn P. Wu, PhD. 311
private string UpIt(string s)
{
s = s.ToUpper();
return s;
}
The following is a complete code that takes user input through a textbox. Depending on the
button being clicked, either “button1” or “button2” will process the user input, and then display
the final result in “textbox1”. It is necessary to note that the instructor purposely declares the “textBox1” control as a member of the “Form1” class so that member of the “Form1” class
(particularly, the “button1_Click()” and “button2_Click()” methods can access “textBox1”.
using System;
using System.Windows.Forms;
using System.Drawing;
public class Form1 : Form
{
private TextBox textBox1;
public Form1()
{
this.Size = new Size (300, 150);
textBox1 = new TextBox();
textBox1.Location = new Point(10, 10);
textBox1.Size = new Size(265, 50);
Controls.Add(textBox1);
Button button1 = new Button();
button1.Location = new Point(10, 60);
button1.Size = new Size(120, 30);
button1.Text = "Celsius to Fahrenheit";
button1.Click += new EventHandler(this.button1_Click);
this.Controls.Add(button1);
Button button2 = new Button();
button2.Location = new Point(150, 60);
button2.Size = new Size(120, 30);
button2.Text = "Fahrenheit to Celsius";
button2.Click += new EventHandler(this.button2_Click);
this.Controls.Add(button2);
}
//event handler as individual method
private void button1_Click(object sender, EventArgs e)
{
// Celsius to Fahrenheit:
double C = Convert.ToDouble(textBox1.Text);
double F = ((C * 9) / 5) + 32;
textBox1.Text = F + "";
}
private void button2_Click(object sender, EventArgs e)
{
Visual C# - Penn P. Wu, PhD. 312
// Fahrenheit to Celsius:
double F = Convert.ToDouble(textBox1.Text);
double C = (F - 32) * 5 / 9;
textBox1.Text = C + "";
}
[STAThread]
public static void Main()
{
Application.Run(new Form1());
}
}
A sample output looks:
and
Textbox In a Windows forms applications, TextBox controls are used to get input from the user or to
display text. The Multiline property, if set to true, allows the user interface to be displayed a
multiline text box; otherwise, it will be displayed as a single-line text box.
textBox1.Multiline = true;
If WordWrap is true (the default), then the text in the control will appear as one or more paragraphs; otherwise it will appear as a list, in which some lines may be clipped at the edge of
the control.
textBox1.WordWrap = true;
If the length of the content is far longer than the height of the TextBox control, set the
ScrollBars property to an appropriate value (such as ScrollBars.Horizontal,
ScrollBars.Vertical, or ScrollBars.Both).
textBox1.ScrollBars = ScrollBars.Vertical;
By setting the PasswordChar property of a TextBox control to a specific character (e.g. "*"),
the TextBox control immediately becomes a password box that displays placeholder characters
while a user types a string.
textBox1.PasswordChar = '*';
By setting a TextBox control’s ReadOnly property to true, the TextBox control becomes a
read-only control. Users can still scroll and highlight text in a text box without allowing
changes.
textBox1.ReadOnly = true;
Unlike the command-line interface, the “\n” (carriage return) escape characters does not work
in a TextBox control. Programmers must use the Environment.NewLine constant to display a
carriage return in a multi-line TextBox.
textBox1.Text = "Line 1" + Environment.NewLine + "Line 2";
while the “\n” in the following statement has no effect.
Visual C# - Penn P. Wu, PhD. 313
textBox1.Text = "Line 1\nLine 2";
Checkbox,
RadioButton,
and GroupBox
Both CheckBox and RadioButton controls have a similar function. They allow the user to
choose from a list of options. Yet, CheckBox controls let the user pick a combination of
options while RadioButton controls allow a user to choose from mutually exclusive options. In
other words, one CheckBox control should be paired with other CheckBox controls to allow
users to check as many options that apply to them while RadioButton controls are suitable for
question that must be either true/false or yes/no.
The following demonstrates how to declare and create instances of CheckBox and RadioButton
controls.
CheckBox checkBox1 = new CheckBox();
radioButton1 = new RadioButton();
Frequently, instances of CheckBoxe or RadioButton classes are grouped by an instance of a
GroupBox class to reflect their similarities. The instance of GroupBox class displays a frame
around a group of CheckBox or RadioButton controls with an optional caption. The following
creates and initializes a GroupBox control.
GroupBox groupBox1 = new GroupBox();
Since the group box is a container control that can be used to define groups of controls, it is
useful for logically grouping a collection of controls on a “form”. The following how to add
two CheckBox controls to a GroupBox by using the “Add()” method of the “Controls”
property.
groupBox1.Controls.Add(checkBox1);
groupBox1.Controls.Add(checkBox2);
Whenever a user clicks a CheckBox control, a “Click” event occurs. The following
demonstrates how to register a “Click” event to the checkBox1 control and associate it with an
event handler named “checkBox1_Click”.
checkBox1.Click += new EventHandler(this.checkBox1_Click);
The following is a sample code of the “checkBox1_Click” event handler. It also demonstrates
how to use the “Checked” property of the “checkBox1” control to determine the control’s state
and perform the response action.
private void checkBox1_Click(object sender, System.EventArgs e)
{
if (!checkBox1.Checked)
{
MessageBox.Show("Uncheked Tokyo.");
}
}
Another useful event is “CheckedChanged” which occurs when the value of the “Checked”
property changes. In the code sample below, when the checkBox2 control’s
“CheckedChanged” event is raised, its AutoCheck property is set to false to disable the status
update. This is useful for situations in which the programmers want to restrict user interaction.
private void checkBox2_CheckedChanged(object sender,
System.EventArgs e)
{
Visual C# - Penn P. Wu, PhD. 314
// Determine the CheckState of the check box.
if (checkBox2.CheckState == CheckState.Checked)
{
// disable the status update
checkBox2.AutoCheck = false;
}
}
The following is the complete code that creates two individual CheckBox controls and places
them in a GroupBox control. Each of the three controls has a set of properties (“Location” and
“Size”) to specify their locations and dimensions. It is necessary to note that both “checkBox1” and “checkBox2” are declared as member of the “Form1” class, so their event handlers (which
are also members of the “Form1” class) can access them.
using System;
using System.Windows.Forms;
using System.Drawing;
public class Form1 : Form
{
private CheckBox checkBox1, checkBox2;
public Form1()
{
this.Size = new Size(250, 190);
//define groupbox
GroupBox groupBox1 = new GroupBox();
groupBox1.Text = "Check the cities you have visited:";
groupBox1.Location = new Point(10, 10);
groupBox1.Size = new Size(215, 60);
this.Controls.Add(groupBox1);
// define the first checkbox
checkBox1 = new CheckBox();
checkBox1.Text = "Tokyo";
checkBox1.Location = new Point(10, 20);
checkBox1.Size = new Size(70, 30);
checkBox1.Checked = true;
checkBox1.Click += new EventHandler(this.checkBox1_Click);
groupBox1.Controls.Add(checkBox1);
// define the 2nd checkbox
checkBox2 = new CheckBox();
checkBox2.Text = "Taipei";
checkBox2.Location = new Point(120, 20);
checkBox2.Size = new Size(70, 30);
checkBox2.Click += new EventHandler(this.checkBox2_CheckedChanged);
groupBox1.Controls.Add(checkBox2);
}
private void checkBox1_Click(object sender, System.EventArgs e)
{
if (!checkBox1.Checked)
{
MessageBox.Show("Uncheked Tokyo.");
}
}
private void checkBox2_CheckedChanged(object sender,
System.EventArgs e)
{
// Determine the CheckState of the check box.
if (checkBox2.CheckState == CheckState.Checked)
Visual C# - Penn P. Wu, PhD. 315
{
// disable the status update
checkBox2.AutoCheck = false;
}
}
[STAThread]
public static void Main()
{
Application.Run(new Form1());
}
}
By setting the Appearance property to Button, a CheckBox control becomes a toggle button.
checkBox1.Appearance = Appearance.Button;
When the Checked property is set to true, the CheckBox control is automatically selected.
checkBox1.Checked = true;
Unlike CheckBox controls, the purpose of RadioButton controls is to limit the user to select
only a single option from a group of choices. The “CheckedChanged” event also applies to
RadioButton controls which occurs when the value of the “Checked” property changes. The
following demonstrates how to register a “CheckedChanged” event to the “radioButton1”
control and associate it with an event handler named “radioButton1_CheckedChanged()”.
radioButton1.CheckedChanged += new
EventHandler(this.radioButton1_CheckedChanged);
The following is the sample code of the “radioButton1_CheckedChanged()” event handler.
private void radioButton1_CheckedChanged(object sender,
System.EventArgs e)
{
//reponsive statements
}
In programming, RadioButton controls are typically paired with other RadioButton controls,
with or without the use of a GroupBox control. The following is a sample code in which the
instructor purposely creates two RadioButton controls for a yes/no type of question, without
using a GroupBox control to host them.
using System;
using System.Windows.Forms;
using System.Drawing;
public class Form1 : Form
{
private Label label1;
public Form1() // properties of the form
{
this.Size = new Size(200, 100);
label1 = new Label();
label1.Text = "Are you a college student?";
label1.AutoSize = true;
label1.Location = new Point(10, 10);
this.Controls.Add(label1);
Visual C# - Penn P. Wu, PhD. 316
RadioButton radioButton1 = new RadioButton();
radioButton1.Text = "Yes";
radioButton1.Size = new Size(50, 30);
radioButton1.Location = new Point(10, 30);
radioButton1.CheckedChanged += new
EventHandler(this.radioButton_CheckedChanged);
this.Controls.Add(radioButton1);
RadioButton radioButton2 = new RadioButton();
radioButton2.Text = "No";
radioButton2.Size = new Size(50, 30);
radioButton2.Location = new Point(70, 30);
radioButton2.CheckedChanged += new
EventHandler(this.radioButton_CheckedChanged);
this.Controls.Add(radioButton2);
}
private void radioButton_CheckedChanged(object sender,
EventArgs e)
{
label1.Text = "You picked " + ((RadioButton) sender).Text;
}
[STAThread]
public static void Main() {
Application.Run(new Form1());
}
}
It is necessary to note that, in the above code, both “radioButton1” and “radioButton2” share
the same event handler named “radioButton_CheckChanged” which is an individual method
that will respond to the “CheckChanged” event, if triggered.
As stated previously, the “sender” parameter represents the control that raises the event (which
is “radioButton1” in this sample code). Since the “sender” parameter is declared as
System.object type, the following statement can cast the data type of “sender” to RadioButton.
Consequently, the data type of “sender” is temporarily converted to RadioButton to more
appropriately represent “radioButton1” within the “radioButton_CheckChanged()” event
handler.
((RadioButton) sender).Text
Technically speaking, if “radioButton1” is checked, the above statement is equivalent to the
following, except the above statement is not specific to any of the two RadioButton controls.
radioButton1.Text
ListBox and
ComboBox
Both ListBox and ComboBox create a list item for selection in a “form”, yet, a ListBox
control can provide single or multiple selections using the “SelectionMode” property while a
ComboBox displays a text box combined with a ListBox to enable the user to select items from
the list or enter a new value. The following demonstrates how to declare and create an instance
of them.
ListBox listBox1 = new ListBox();
ComboBox comboBox1 = new ComboBox();
The following sets the dimension and location of a ListBox control and adds it to a “form”.
Visual C# - Penn P. Wu, PhD. 317
listBox1.Size = new Size(200, 100);
listBox1.Location = new Point(10,10);
this.Controls.Add(listBox1);
A ListBox control can provide single or multiple selections using the “SelectionMode”
property. The following, for example, sets the selection mode to multiple and extended.
listBox1.SelectionMode = SelectionMode.MultiExtended;
By setting the “MultiColumn” property to true, the ListBox control can display items in
multiple columns.
listBox1.MultiColumn = true;
The “EndUpdate()” method allows the ListBox to refresh and display the new items.
listBox1.EndUpdate();
The SetSelected(i, bool) method set the specified items to be selected by default, in which i is
the index starting at 0 while bool is either true (means to select the specified item) or false (to
unselect). The following, for example, selects three items from the ListBox. They the second
(index 1), the forth (index 3), and the sixth (index 5) items.
listBox1.SetSelected(1, true);
listBox1.SetSelected(3, true);
listBox1.SetSelected(5, true);
The SelectedItem property can designate currently selected item.
listBox1.SelectedItem = "Banana";
Items in a ListBox can be managed using the methods of the “Items” property.
• The Items.Add() method adds options to the list.
• The Items.Insert() method inserts new option(s) to the list.
• The Items.Remove() method removes option(s) from the list.
The following is a sample code that demonstrates how to add three items, “Apple”, “Orange”, and “Banana”, to the “listBox1” control and set the “Banana” item as the selected item.
listBox1.Items.Add("Apple");
listBox1.Items.Add("Orange");
listBox1.Items.Add("Banana");
listBox1.SelectedItem="Banana";
The “SelectedIndexChanged” event occurs when the “SelectedIndex” property or the
“SelectedIndices” collection has changed. The following demonstrates how to register an
“SelectedIndexChanged” event to the listBox1 control and associate it with an event handler
named “listBox1_SelectedIndexChanged()” event handler.
listBox1.SelectedIndexChanged += new
EventHandler(this.listBox1_SelectedIndexChanged);
The following is a sample event handler in which the instructor purposely create an instance of
ListBox named “lst”. Then, the “lst” object is set to be the control represented by the “sender”
parameter (which is “listBox1” and is the one that raises the event). Consequently, “lst” represents “listBox1” in the “listBox1_SelectedIndexChanged()” event hander. The event
handler will display the value of the selected item and its index.
Visual C# - Penn P. Wu, PhD. 318
private void listBox1_SelectedIndexChanged(object sender,
System.EventArgs e)
{
ListBox lsb = (ListBox) sender;
MessageBox.Show(lsb.SelectedItem.ToString() + "\n" +
lsb.SelectedIndex);
}
The following is the complete code.
using System;
using System.Windows.Forms;
using System.Drawing;
public class Form1 : Form
{
public Form1()
{
Size=new Size(150,150);
ListBox listBox1 = new ListBox();
and
listBox1.Location = new Point(10,10);
listBox1.Width = 100;
listBox1.Height = 50;
listBox1.Items.Add("Apple");
listBox1.Items.Add("Orange");
listBox1.Items.Add("Banana");
listBox1.SelectedItem="Banana";
listBox1.SelectedIndexChanged += new
EventHandler(this.listBox1_SelectedIndexChanged);
this.Controls.Add(listBox1);
}
private void listBox1_SelectedIndexChanged(object sender,
System.EventArgs e)
{
ListBox lsb = (ListBox) sender;
MessageBox.Show(lsb.SelectedItem.ToString() + "\n" +
lsb.SelectedIndex);
}
[STAThread]
public static void Main()
{
Application.Run(new Form1());
}
}
Similar to ListBox, programmers can use the “Add()” method to add items to a ComboBox,
and use the “SelectedItem” property to designate the selected item.
comboBox1.Items.Add("HBO");
comboBox1.Items.Add("CNN");
comboBox1.Items.Add("PBS");
comboBox1.Items.Add("FOX");
Visual C# - Penn P. Wu, PhD. 319
comboBox1.Items.Add("ABC");
comboBox1.SelectedItem="PBS";
Programmer can also assign an array of System.object type using AddRange() method. The
above codes can be written as the following.
comboBox1.Items.AddRange(new object[] {"HBO", "CNN", "PBS",
"FOX", "ABC"});
comboBox1.SelectedItem="PBS";
The DropDownStyle property specifies whether the list is always displayed or whether the list
is displayed in a drop-down. There three possible values: DropDown, DropDownList, and
Simple. By the way, “DropDown” is the default value which specifies that the list is displayed
by clicking the down arrow and that the text portion is editable. The “Simple” option specifies
that the list is always visible and that the text portion is editable.
comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
The DrawMode property gets or sets a value indicating whether your code or the operating
system will handle drawing of elements in the list.
comboBox1.DrawMode = DrawMode.OwnerDrawVariable;
Both DropDownWidth and DropDownHeight properties can set the width and height of the
of the drop-down portion of a combo box.
ComboBox1.DropDownWidth = 250;
The “SelectedIndexChanged” event occurs when the “SelectedIndex” property of a ComboBox
control has changed. The following demonstrates how to associate the event-handling method
with the SelectedIndexChanged event.
comboBox1.SelectedIndexChanged += new
System.EventHandler(comboBox1_SelectedIndexChanged);
The following is a sample code for the event handler. It declares an instance of the ComboBox
class named “cmb” which will represent the “comboBox1” control within the event handler because the “sender” parameter transfers its reference to “cmb”.
private void comboBox1_SelectedIndexChanged(object sender,
System.EventArgs e)
{
ComboBox cmb = (ComboBox) sender;
MessageBox.Show(cmb.SelectedItem + "\n" + cmb.SelectedIndex);
}
The following is a complete sample code.
using System;
using System.Windows.Forms;
using System.Drawing;
public class Form1 : Form
{
public Form1()
{
Size=new Size(150, 150);
Visual C# - Penn P. Wu, PhD. 320
ComboBox comboBox1 = new ComboBox();
comboBox1.Location = new Point(10, 10);
comboBox1.Width = 50;
comboBox1.Height = 50;
comboBox1.DropDownWidth = 100;
comboBox1.Items.AddRange(new object[] {"HBO", "CNN", "PBS",
"FOX", "ABC"});
comboBox1.SelectedItem="PBS";
comboBox1.SelectedIndexChanged += new
System.EventHandler(comboBox1_SelectedIndexChanged);
this.Controls.Add(comboBox1);
}
private void comboBox1_SelectedIndexChanged(object sender,
System.EventArgs e)
{
ComboBox cmb = (ComboBox) sender;
MessageBox.Show(cmb.SelectedItem + "\n" + cmb.SelectedIndex);
}
[STAThread]
public static void Main()
{
Application.Run(new Form1());
}
}
DateTimePicker The “DateTimePicker” control is used to allow the user to select a date and time, and then
display that date and time in the specified format. When used to represent a date, the
DateTimePicker control appears in two parts: (1) a drop-down list with a date represented in text, and (2) a calendar that appears when you click the down-arrow next to the list.
The following demonstrates how to declare and create a new “DateTimePicker” control.
DateTimePicker dateTimePicker1 = new DateTimePicker();
The following is a simple code that will create a drop-down menu which contains a dynamic
calendar. The calendar is an instance of the MonthCalendar class which displays a monthly calendar allowing the user to select a date.
using System;
using System.Windows.Forms;
using System.Drawing;
public class Form1 : Form
{
private DateTimePicker dateTimePicker1;
public Form1()
{
dateTimePicker1 = new DateTimePicker();
dateTimePicker1.Location = new Point(10, 10);
this.Controls.Add(dateTimePicker1);
}
Visual C# - Penn P. Wu, PhD. 321
[STAThread]
public static void Main()
{
Application.Run(new Form1());
}
}
The “MinDate” property can set the minimum date and time that can be selected in the control
while the “MaxDate” property sets the maximum date and time that can be selected in the
control, yet, the default is 12/31/9998. The value of date and time must be the “DateTime” type.
dateTimePicker1.MinDate = new DateTime(2000, 1, 1);
dateTimePicker1.MaxDate = DateTime.Today;
The DateTimePicker can work with the “ValueChanged” event which occurs when the “Value”
property of the DateTimePicker changes. In other words, the “ValueChanged” event occurs
when a new data and time is picked. The following demonstrates how to register the event and
associate it with an event handler named “DateTimePicker1_ValueChanged()”.
dateTimePicker1.ValueChanged += new
EventHandler(this.DateTimePicker1_ValueChanged);
The following is a sample event handler. It obtains the current date and time the control is set
to be from the “Value” property of the “dateTimePicker1” control, and then assigns the data and time value to the “Text” property of the “form” which is represented by the “this”
keyword.
private void DateTimePicker1_ValueChanged(Object sender,
EventArgs e)
{
this.Text = dateTimePicker1.Value + "";
}
The “CustomFormat” property can specify how to display the date values in a custom-defined
format like “MMMM dd, yyyy – dddd”.
dateTimePicker1.CustomFormat = "MMMM dd, yyyy - dddd";
With the above custom-defined format, the “Format” property must be set to “Custom” so that
the custom format will take effect.
dateTimePicker1.Format = DateTimePickerFormat.Custom;
The “ShowCheckBox” property, if set to true, there will be a check box displayed on the left
of the selected date.
dateTimePicker1.ShowCheckBox = true;
By setting the “ShowUpDown” property to true, the “DateTimePicker” control is displayed as
a spin button control.
dateTimePicker1.ShowUpDown = true;
The appearance of the calendar of a “DateTimePicker” control can change by modifying values
of the following properties.
Visual C# - Penn P. Wu, PhD. 322
Property Description CalendarForeColor the foreground color of the calendar.
CalendarFont font style applied to the calendar.
CalendarTitleBackColor background color of the calendar title.
CalendarTitleForeColor foreground color of the calendar title.
CalendarTrailingForeColor foreground color of the calendar trailing dates.
CalendarMonthBackground background color of the calendar month.
The following demonstrates how to use the above properties.
dateTimePicker1.CalendarForeColor = Color.Yellow;
dateTimePicker1.CalendarMonthBackground = Color.Aqua;
dateTimePicker1.CalendarFont = new Font("Courier New", 8.25F,
FontStyle.Italic, GraphicsUnit.Point);
With the use of Globalization namespace, programmers can convert the date value from
Western calendar to a foreign calendar, such as Chinese lunar calendar.
using System.Globalization;
The ChineseLunisolarCalendar class can represent time in divisions, such as months, days,
and years. Years are calculated using the Chinese calendar, while days and months are
calculated using the lunisolar calendar. In the following code snippets, “dt” is a DateTime
instance that will get the date and time value from the DateTimePicker. The
ChineseLunisolarCalendar class then converts the date values to the equivalent ones in
Chinese calendar and stores them in three int variables: d, m, y. The value of “dt” is re-assigned
to new DateTime(y, m, d).
DateTime dt = dateTimePicker1.Value;
ChineseLunisolarCalendar ch = new ChineseLunisolarCalendar();
int d = ch.GetDayOfMonth(dt); // convert to Chinese value
int m = ch.GetMonth(dt); // convert to Chinese month
int y = ch.GetYear(dt); // convert to Chinese year
dt = new DateTime(y, m, d);
Events for keyboard and
mouse
Many “forms” accept user inputs from the keyboard and mouse. Each key on the keyboard displays a symbol, a letter, or a combination of those. When the user presses a key, the
keyboard sends a signal to operating system which will analyze what the signal means. If the
application has an event and its event handler for responding to the signal, the application may
produce the expected result. Similarly, the computer mouse has buttons (or wheel) for clicking.
When the user moves the mouse, or presses or releases a mouse button, a mouse event is
raised.
The .NET Framework supports the KeyPress event which occurs when the user presses a key.
However, a key pressing is further separated to two events: KeyDown and KeyUp. Both
KeyDown and KeyUp event are implemented by instances of the KeyEventArgs type with a
delegate of the KeyEventHandler class. The following illustrates the generic format of the
Visual C# - Penn P. Wu, PhD. 323
event registration which registers an “KeyDown” event to the “textBox1” control as well as its
event handler (which is a method named “textBox_KeyDown”).
textBox1.KeyDown += new KeyEventHandler(this.textBox1_KeyDown);
The following is a sample event handler. When the “textBox1” is active (which means the
mouse cursor is currently placed on “textBox1”), the size of the “form” will change to 100 ×
100 pixel.
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
this.Size = new Size(100, 100);
}
Similarly, the following demonstrates how to use the “KeyUp” event.
textBox1.KeyUp += new KeyEventHandler(this.textBox1_KeyUp);
........ private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
this.Size = new Size(300, 300);
}
The “KeyPress” event occurs after the “KeyDown” event but before the “KeyUp” event.
However, unlike “KeyUp” and “KeyDown” events, the “KeyPress” event only works with
character keys. Arrow keys, PageUp, Esc, or Alt keys cannot hire a “KeyPress” event. Event
data of the “KeyPress” event is implemented by an instance of the KeyPressEventArgs class
and it uses the KeyPressEventHandler delegate to associate with an event handler.
textBox1.KeyPress += new
KeyPressEventHandler(this.textBox1_KeyPress);
...........
private void textBox1_KeyPress(object sender, KeyPressEventArgs
e)
{
e.Handled = true;
switch (e.KeyChar)
{
case 'a': textBox1.Text = "APPLE"; break;
case 'b': textBox1.Text = "BANANA"; break;
case 'c': textBox1.Text = "CHERRY"; break;
case 'd': textBox1.Text = "DRAGON FRUIT"; break;
}
}
The Handled property of the KeyPressEventArgs class, when being set to true, can prevent
the letter from being entered to “textBox1”. The KeyChar property returns the key that was
pressed. In the above example, when “a” is pressed, the KeyChar property holds the value ‘a’
and “textBox1” is forced to display “APPLE”. When “b” is pressed, “textBox1” displays
“BANANA”. Each key is assigned a code for the operating system to recognize. By the way,
for an uppercase letter or an upper base symbol, the user must press Shift + the key. The
character would be identified as one entity.
The mouse is another object that is attached to the computer allowing the user to interact with
the machine. Typically, a computer mouse could be equipped with two, three, or more buttons.
When a mouse has two buttons, one is usually located on the left and the other is located on the
right. When a mouse has three buttons, the third will usually be placed in the middle of the
other two. By the way, the middle button can also be a round object referred to as a wheel.
Visual C# - Penn P. Wu, PhD. 324
C# programmers can use the following mouse event provided by the .NET Framework.
Interestingly, the MouseEnter, MouseHover, and MouseLeave events rely on an instance of the EventArgs class to implement their event data, while the MouseUp, MouseDown, and
MouseMove must rely on an instance of the MouseEventArgs class. The .NET Framework
provides the MouseEventArgs class as a specialized class that provides data only for the
MouseUp, MouseDown, and MouseMove events. The EventArgs class, on the other hand, is
the base class for classes that contain event data and provides a value to use for events that do
not include event data.
Mouse Event Description Data Class MouseEnter Before using a control using the mouse, the user
must first position the mouse cursor on the
control. When this happens, the control fires a
MouseEnter event.
EventArgs
MouseHover If the user positions the mouse on a control and
hovers over it, a MouseHover event is fired.
EventArgs
MouseLeave When the user moves the mouse pointer away
from a control, the control fires a MouseLeave
event.
EventArgs
MouseDown When a button is pressed and is pressed down, a
MouseDown event is fired.
MouseEventArgs
MouseUp Occurs when the mouse pointer is over the control
and a mouse button is released.
MouseEventArgs
MouseMove Whenever the mouse is being moved on top of a
control, a MouseMove event is raised.
MouseEventArgs
When an event relies on the MouseEventArgs class, the delegate must be
MouseEventHandler. For those rely on the EventArgs class, their delegate is the generic delegate: EventHandler.
The following demonstrates how to register a “MouseMove” event to the “textBox1” control
and associate it with an event handler named “textBox1_MouseMove()”. The format applies to
“MouseUp” and “MouseDown” events as well.
textBox1.MouseMove += new
MouseEventHandler(this.textBox1_MouseMove);
..........
private void textBox1_MouseMove(object sender, MouseEventArgs e)
{
textBox1.Text = "";
}
The following demonstrates how to register a “MouseEnter” event to the “textBox1” control
and associate it with an event handler named “textBox1_MouseEnter()”. The same format
applies to “MouseHover” and “MouseLeave” events, too.
Visual C# - Penn P. Wu, PhD. 325
textBox1.MouseEnter += new
EventHandler(this.textBox1_MouseEnter);
...............
private void textBox1_MouseEnter(object sender, EventArgs e)
{
textBox1.Hide();
}
In the following example, the instance “e” of the MouseEventArgs class provides the event
data of the “MouseMove” event. Its X and Y properties holds the x- and y-coordinate of the
current mouse location. When the mouse cursor moves inside the form, the x and y values is displayed in a “Label” control. The position of the “Label” control will move along the mouse
cursor. By the way, the “this” keyword refers to the “form”.
using System;
using System.Windows.Forms;
using System.Drawing;
public class Form1 : Form
{
private Label label1;
public Form1()
{
label1 = new Label();
label1.AutoSize = true;
this.Controls.Add(label1);
this.MouseMove += new MouseEventHandler(this.Form1_MouseMove);
}
public void Form1_MouseMove(object sender, MouseEventArgs e)
{
label1.Location = new Point(e.X, e.Y);
label1.Text = "(" + e.X + " , " + e.Y +")";
}
[STAThread]
public static void Main()
{
Application.Run(new Form1());
}
}
The trick is that the following statement sets the values of x- and y-coordinates of the mouse
cursor as the location of “label1”.
label1.Location = new Point(e.X, e.Y);
Review Questions
1. Given the following code segment, which is the correct way to create an instance of the Form1 class?
public class Form1 : Form {}
A. Application.Run(new Form1);
B. Application.Run(Form1());
C. Application.Run(new Form1());
D. Application.Run(new Form1(Form));
2. Given the following code segment, which is the constructor that actually creates a Label
control?
Visual C# - Penn P. Wu, PhD. 326
Label label1 = new Label();
A. Label
B. label1
C. new
D. Label()
3. Which is the correct to specify the size of a form?
A. this.Size = new Size (150, 75);
B. this,Size = 150, 75;
C. Form.Width=150; Form.Height=75;
D. Form Size = new Size (150, 75);
4. Which statement can register a "Click" event to "label1" control and associate the event to an
event handler named "label1_Click()"?
A. label1.Click = new EventHandler(this.label1_Click());
B. label1.Click + new EventHandler(this.label1_Click());
C. label1.Click == new EventHandler(this.label1_Click());
D. label1.Click += new EventHandler(this.label1_Click());
5. Which is the correct way to register a TextChanged event to a TextBox object named
"textBox1" and will call an event handler named "textBox1_TextChanged)?
A. textBox1.TextChanged += new EventHandler(this.textBox1_TextChanged);
B. textBox1.TextChanged = new EventHandler(this.textBox1_TextChanged); C. textBox1.TextChanged = new EventHandler(this(textBox1_TextChanged));
D. textBox1.TextChanged += new EventHandler(this.textBox1_TextChanged());
6. Given the following code segment, which is the statement you need to add in order to
display the Label control on the Windows form?
public class Form1 : Form {
public Form1() {
Label label1 = new Label();
label1.Text = "Show me";
label1.Location = new Point(10, 10);
label1.AutoSize = true;
}
}
A. label1.Enabled = true;
B. label1.Show();
C. label1.Visible = true;
D. Controls.Add(label1);
7. Given the following code, the __ field is a Windows Forms Label Control.
public class Form1 : Form
{
private Container components;
private Label label1;
....
}
A. Container
B. Form1
C. components D. label1
Visual C# - Penn P. Wu, PhD. 327
8. Given the following code, __.
public static void Main()
{
Application.Run(new Form1());
}
A. Main() runs the program by calling the static Run()method
B. The Run() method's parameter is a new instance of the Form1 class C. Run() is a static method
D. All of the above
9. Given the following code segment, which statement best explain why the declaration and
instantiation of the Label controls are placed at two different lines?
public class Form1 : Form {
Label label1;
public Form1() {
label1 = new Label();
}
public changeIt() {
label1.Text = "Changed";
}
}
A. "label1" is declared as an empty object, so it can be instantiated on demand to save some
memory space.
B. "label1" is declared as a member of the "Form1" class, so the changeIt() function of the "Form1" class can access it.
C. "label1" is declared as a subclass, so it can inherit the "Form1" class.
D. It does not have any effect and will not make any difference in this case.
10. With the assumption that a "MouseMove" event has been registered with the "textBox1"
control, which is the most appropriate candidate for being the event handler?
A. private void textBox1_MouseMove(object sender, MouseMoveEventArgs e) { }
B. private void textBox1_MouseMove(object sender, MouseClickEventArgs e) { }
C. private void textBox1_MouseMove(object sender, MouseEventArgs e) { }
D. private void textBox1_MouseMove(object sender, EventArgs e) { }
Visual C# - Penn P. Wu, PhD. 328
Lab #10 Hand-Coding Windows Forms Applications
Learning Activity #1: Label, TextBox, Button
1. Create a new directory called C:\CIS218 if it does not exist.
2. Launch the Developer Command Prompt.
3. In the prompt, type cd c:\cis218 and press [Enter] to change to the C:\CIS218 directory.
4. In the prompt, type notepad lab10_1.cs and press [Enter] to use Notepad to create a new source file called
lab10_1.cs with the following contents:
using System;
using System.Drawing;
using System.Windows.Forms;
public class Form1 : Form
{
//fields of Form1 class
private double a, b, c, x1, x2;
private TextBox textBox1, textBox2, textBox3, textBox4; //declare as class member
public Form1() //default constructor
{
this.Size = new Size(300, 225); // set size of the form
Label label1 = new Label(); //declare as member of Form1 constructor
label1.Text = "a:";
label1.Size = new Size(20, 30);
label1.Location = new Point(10, 10);
this.Controls.Add(label1); //add control to the form
textBox1 = new TextBox();
textBox1.Size = new Size(100, 30);
textBox1.Location = new Point(30, 10);
//event handler registration
textBox1.TextChanged += new EventHandler(this.textBox1_TextChanged);
this.Controls.Add(textBox1);
Label label2 = new Label(); //declare as member of Form1 constructor
label2.Text = "b:";
label2.Size = new Size(20, 30);
label2.Location = new Point(10, 40);
this.Controls.Add(label2);
textBox2 = new TextBox();
textBox2.Size = new Size(100, 30);
textBox2.Location = new Point(30, 40);
this.Controls.Add(textBox2);
Label label3 = new Label(); //declare as member of Form1 constructor
label3.Text = "a:";
label3.Size = new Size(20, 30);
label3.Location = new Point(10, 70);
this.Controls.Add(label3);
textBox3 = new TextBox(); //declare as member of Form1 constructor
Visual C# - Penn P. Wu, PhD. 329
textBox3.Size = new Size(100, 30);
textBox3.Location = new Point(30, 70);
this.Controls.Add(textBox3);
Button button1 = new Button();
button1.Text = "Solve";
button1.Size = new Size(50, 30);
button1.Location = new Point(140, 60);
button1.Click += new EventHandler(button1_Click); //event handler registration
this.Controls.Add(button1);
textBox4 = new TextBox();
textBox4.Size = new Size(265, 70);
textBox4.Location = new Point(10, 100);
textBox4.Multiline = true;
this.Controls.Add(textBox4);
}
private void textBox1_TextChanged(object sender, EventArgs e)//event handler
{
textBox4.Text = ""; //clear textBox4
}
private void button1_Click(object sender, EventArgs e) //event handler
{
a = Convert.ToDouble(textBox1.Text);
b = Convert.ToDouble(textBox2.Text);
c = Convert.ToDouble(textBox3.Text);
x1 = (-b + Math.Sqrt(b*b-4*a*c)) / 2*a;
x2 = (-b - Math.Sqrt(b*b-4*a*c)) / 2*a;
textBox4.Text = "Equation: " + a + "x^2 + " + b + "x + " + c + " = 0" +
Environment.NewLine + Environment.NewLine +
"Solution: " + Environment.NewLine +
"x1: " + x1 + Environment.NewLine +
"x2: " + x2 + Environment.NewLine;
}
[STAThread]
public static void Main()
{
Application.Run(new Form1()); // create the form
}
}
5. Compile and test the program. A sample output looks:
6. Download the “assignment template”, and rename it to lab1.doc if necessary. Capture a screen shot similar to
the above and paste it to the Word document named lab10.doc (or .docx).
Learning Activity #2: Temperature Converter - Radio Buttons
Visual C# - Penn P. Wu, PhD. 330
1. Under the C:\cis218 directory, use Notepad to create a new source file called lab10_2.cs with the following
contents:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
public class Form1 : Form
{
private string result, measure;
private Button button1;
private TextBox textBox1, textBox2;
private GroupBox groupBox1;
private RadioButton radioButton1, radioButton2;
public Form1()
{
this.Text = "Temperature Converter";
Label label1 = new Label();
label1.Text = "Enter the degree:";
label1.AutoSize = true;
label1.Location = new Point(10, 10);
this.Controls.Add(label1);
textBox1 = new TextBox();
textBox1.Size = new Size(90, 35);
textBox1.Location = new Point(110, 10);
this.Controls.Add(textBox1);
button1 = new Button();
button1.Text = "Convert";
button1.Size = new Size(70, 30);
button1.Location = new Point(205, 10);
button1.Click += new EventHandler(button1_Click);
this.Controls.Add(button1);
groupBox1 = new GroupBox();
groupBox1.Text = "Measurement:";
groupBox1.Size = new Size(265, 50);
groupBox1.Location = new Point(10, 40);
radioButton1 = new RadioButton();
radioButton1.Text = "Fahrenheit to Celsius";
radioButton1.Name = "F2C";
radioButton1.Size = new Size(100, 30);
radioButton1.Location = new Point(10, 15);
radioButton1.CheckedChanged += new EventHandler(radioButton_CheckedChanged);
groupBox1.Controls.Add(this.radioButton1);
radioButton2 = new RadioButton();
radioButton2.Text = "Celsius to Fahrenheit";
radioButton2.Name = "C2F";
radioButton2.Size = new Size(100, 30);
radioButton2.Location = new Point(110, 15);
radioButton2.CheckedChanged += new EventHandler(radioButton_CheckedChanged);
Visual C# - Penn P. Wu, PhD. 331
groupBox1.Controls.Add(this.radioButton2);
this.Controls.Add(groupBox1);
textBox2 = new TextBox();
textBox2.Multiline = true;
textBox2.Size = new Size(265, 150);
textBox2.Location = new Point(10, 95);
this.Controls.Add(textBox2);
}
private void radioButton_CheckedChanged(object sender, EventArgs e)
{
RadioButton rb = (RadioButton) sender;
if (rb.Checked) { measure = rb.Name; }
if (rb == null) { MessageBox.Show("Please select a measurement."); }
}
private void button1_Click(object sender, EventArgs e)
{
switch(measure)
{
case "F2C":
double fd = Convert.ToDouble(textBox1.Text);
result += fd + "F = " + Math.Round((fd-32)*(5.0/9.0), 2) +
"C" + Environment.NewLine;
break;
case "C2F":
double cd = Convert.ToDouble(textBox1.Text);
result += cd + "C = " + Math.Round(((cd*9.0/5.0)+32), 2) +
"F" + Environment.NewLine;
break;
}
textBox2.Text = result;
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form1());
}
}
2. Compile and test the program. A sample output looks:
3. Capture a screen shot similar to the above and paste it to the Word document named lab10.doc (or .docx).
Learning Activity #3: ComboBox
Visual C# - Penn P. Wu, PhD. 332
1. Under the C:\cis218 directory, use Notepad to create a new source file called lab10_3.cs with the following
contents:
using System;
using System.Windows.Forms;
using System.Drawing;
public class Form1 : Form
{
private ComboBox comboBox1, comboBox2;
private TextBox textBox1;
private string bloodtype, rhtype;
public Form1() // properties of the form
{
// define the size of the form
this.Size = new Size(320, 200);
Label label1 = new Label();
label1.Text = "Blood Type:";
label1.AutoSize = true;
label1.Location = new Point(10, 10);
this.Controls.Add(label1);
comboBox1 = new ComboBox();
comboBox1.Location=new Point(10,35);
comboBox1.Width = 100;
comboBox1.Height = 25;
comboBox1.Items.Add("A");
comboBox1.Items.Add("B");
comboBox1.Items.Add("O");
comboBox1.Items.Add("AB");
comboBox1.SelectedItem="O";
comboBox1.SelectedValueChanged += new
EventHandler(comboBox1_SelectedValueChanged);
this.Controls.Add(comboBox1);
Label label2 = new Label();
label2.Text = "RH Type:";
label2.AutoSize = true;
label2.Location = new Point(120, 10);
this.Controls.Add(label2);
comboBox2 = new ComboBox();
comboBox2.Location=new Point(120,35);
comboBox2.Width = 100;
comboBox2.Height = 25;
comboBox2.Items.AddRange(new object[] {"Positive", "Negative"});
comboBox1.SelectedItem="Positive";
comboBox2.SelectedValueChanged += new
EventHandler(comboBox2_SelectedValueChanged);
this.Controls.Add(comboBox2);
Button button1 = new Button();
button1.Text = "Check";
button1.Size = new Size(70, 30);
button1.Location = new Point(225, 30);
button1.Click += new EventHandler(button1_Click);
Visual C# - Penn P. Wu, PhD. 333
this.Controls.Add(button1);
textBox1 = new TextBox();
textBox1.Size = new Size(285, 75);
textBox1.Location = new Point(10, 70);
textBox1.Multiline = true;
this.Controls.Add(textBox1);
}
private void comboBox1_SelectedValueChanged(object sender, EventArgs e)
{
bloodtype = comboBox1.SelectedItem.ToString();
textBox1.Text = ""; // clear textBox1
}
private void comboBox2_SelectedValueChanged(object sender, EventArgs e)
{
rhtype = comboBox2.SelectedItem.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
string str = "";
if (bloodtype == "A" && rhtype=="Negative")
{ str ="This blood type has A marker only."; }
if (bloodtype == "A" && rhtype=="Positive")
{ str ="This blood type has A marker and Rh factor, but not B marker. Along with
O positive, it is one of the two most common blood types."; }
if (bloodtype == "B" && rhtype=="Negative")
{ str ="This blood type has B marker only."; }
if (bloodtype == "B" && rhtype=="Positive")
{ str ="This blood type has B marker and Rh factor, but not A marker."; }
if (bloodtype == "O" && rhtype=="Negative")
{ str = "This blood type does not have A or B markers, and it does not have Rh
factor.";}
if (bloodtype == "O" && rhtype=="Positive")
{ str ="This blood type does not have A or B markers, but it does have Rh
factor. O positive blood is one of the two most common blood types (the other
being A positive)."; }
if (bloodtype == "AB" && rhtype=="Negative")
{ str ="This blood type has A and B markers, but not Rh factor."; }
if (bloodtype == "AB" && rhtype=="Positive")
{ str ="This blood type has all three types of markers — A, B, and Rh
factor."; }
textBox1.Text = "Blood type: " + bloodtype + Environment.NewLine +
"RH type: " + rhtype + Environment.NewLine + "Description: " +
str;
}
[STAThread]
public static void Main()
{
Visual C# - Penn P. Wu, PhD. 334
Application.Run(new Form1());
}
}
2. Compile and test the program. A sample output looks:
3. Capture a screen shot similar to the above and paste it to the Word document named lab10.doc (or .docx).
Learning Activity #4: Keyboard and Mouse events
1. Under the C:\cis218 directory, use Notepad to create a new source file called lab10_4.cs with the following
contents:
using System;
using System.Windows.Forms;
using System.Drawing;
public class Form1 : Form
{
private Label label1, label2;
public Form1()
{
this.Height = 200;
label1 = new Label();
label1.Size = new Size(50, 50);
label1.Location = new Point(10, 10);
label1.BackColor = Color.Red;
this.Controls.Add(label1);
label2 = new Label();
label2.Size = new Size(50, 50);
label2.Location = new Point(120, 10);
label2.BackColor = Color.Blue;
this.Controls.Add(label2);
this.KeyPress += new KeyPressEventHandler(this.this_KeyPress);
this.KeyUp += new KeyEventHandler(this.this_KeyUp);
this.MouseDown += new MouseEventHandler(this.this_MouseDown);
this.MouseUp += new MouseEventHandler(this.this_MouseUp);
}
private void this_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = true;
switch (e.KeyChar)
{
case 'r': label1.BackColor = Color.Orange; break;
case 'l': label2.BackColor = Color.Cyan; break;
}
Visual C# - Penn P. Wu, PhD. 335
}
private void this_KeyUp(object sender, KeyEventArgs e)
{
label1.BackColor = Color.Red;
label2.BackColor = Color.Blue;
}
private void this_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
label1.Size = new Size(100, 100);
}
else if (e.Button == MouseButtons.Right)
{
label2.Size = new Size(100, 100);
}
else { }
}
private void this_MouseUp(object sender, MouseEventArgs e)
{
label1.Size = new Size(50, 50);
label2.Size = new Size(50, 50);
}
[STAThread]
public static void Main()
{
Application.Run(new Form1());
}
}
2. Compile and test the program. Press “r” and then “l” keys a few time. Then, click left and right mouse buttons a
few times. A sample output looks:
3. Capture a screen shot similar to the above and paste it to the Word document named lab10.doc (or .docx).
Learning Activity #5: Convert a data to Chinese lunar calendar
1. Under the C:\cis218 directory, use Notepad to create a new source file called lab10_5.cs with the following
contents:
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Globalization;
public class Form1 : Form
{
private DateTimePicker dateTimePicker1;
private TextBox textBox1;
public Form1()
Visual C# - Penn P. Wu, PhD. 336
{
this.Size = new Size(300, 250);
Label label1 = new Label();
label1.Text = "Pick a Western calendar date:";
label1.Location = new Point(10, 10);
label1.AutoSize = true;
this.Controls.Add(label1);
dateTimePicker1 = new DateTimePicker();
dateTimePicker1.Value = DateTime.Now; //default to now
dateTimePicker1.Location = new Point(10, 30);
dateTimePicker1.ValueChanged += new
EventHandler(this.DateTimePicker1_ValueChanged);
this.Controls.Add(dateTimePicker1);
textBox1 = new TextBox();
textBox1.Size = new Size(265, 70);
textBox1.Location = new Point(10, 60);
textBox1.Multiline = true;
this.Controls.Add(textBox1);
}
private void DateTimePicker1_ValueChanged(Object sender, EventArgs e)
{
textBox1.Text = "'"; //clear textBox1
DateTime dt = dateTimePicker1.Value; //picked Western date
DateTime cdt = getChineaseLunar(dt); //converted Chinease date
textBox1.Text = "Picked Western date: " + dt.ToShortDateString() + " (M/D/Y)" +
Environment.NewLine +
"Chinese lunar date: " + cdt.ToShortDateString();
}
private DateTime getWestern(DateTime dt)
{
GregorianCalendar gr = new GregorianCalendar();
int gd = gr.GetDayOfMonth(dt); // convert to western value
int gm = gr.GetMonth(dt);
int gy = gr.GetYear(dt);
DateTime wdt = new DateTime(gy, gm, gd);
return wdt;
}
private DateTime getChineaseLunar(DateTime dt)
{
ChineseLunisolarCalendar ch = new ChineseLunisolarCalendar();
int cd = ch.GetDayOfMonth(dt); // convert to Chinese value
int cm = ch.GetMonth(dt); // convert to Chinese month
int cy = ch.GetYear(dt); // convert to Chinese year
DateTime cdt = new DateTime(cy, cm, cd);
return cdt;
}
[STAThread]
public static void Main()
{
Visual C# - Penn P. Wu, PhD. 337
Application.Run(new Form1());
}
}
2. Compile and test the program. A sample output looks:
3. Capture a screen shot similar to the above and paste it to the Word document named lab10.doc (or .docx).
Submittal
1. Complete all the 5 learning activities.
2. Create a .zip file named lab10.zip containing ONLY the following self-executable files.
• Lab10_1.exe
• Lab10_2.exe
• Lab10_3.exe
• Lab10_4.exe
• Lab10_5.exe
• Lab10.doc (or .docx) [You may be given zero point if this Word document is missing]
3. Log in to course site and enter the course site.
4. Upload the zipped file as response to question 11.
Programming Exercise:
1. Use Notepad to create a new file named ex10.cs with the following heading lines (be sure to replace
YourFullNameHere with the correct one):
//File Name: ex10.cs
//Programmer: YourFullNameHere
1. Under the above two heading lines, write C# codes to create a generic Windows “form” (not message box) with
two “Button” controls in it. Set its size of the form to (250, 250).
2. Place one “Button” control at the point (10, 10) and set its caption to “Shrink”. Then, place the second “Button”
control at the point (120, 10) and set its caption to “Enlarge”.
3. Write codes to add two event handlers for each of the two “Button” controls. When the “Shirnk” button is
clicked, change the size of the form to (250, 100). When the “Enlarge” button is clicked, change the size of the
form back to (250, 250), as shown below.
Change from to
Visual C# - Penn P. Wu, PhD. 338
2. Download the “programming exercise template”, and rename it to ex10.doc. Capture a screen shot similar to the
above figure and then paste it to the Word document named “ex10.doc” (or .docx).
3. Compress the source code (ex10.cs), the executable (ex10.exe), and the Word document (ex10.doc or .docx) to
a .zip file named “ex10.zip”. You may be given zero point if any of the required file is missing.
Grading Criteria:
• You must be the sole author of the codes.
• You must meet all the requirements in order to earn credits. You will receive zero if you use Visual Studio (C#)
IDE to generate the code.
• No partial credit is given.