- •Contents at a Glance
- •Table of Contents
- •Acknowledgments
- •Introduction
- •Who This Book Is For
- •Finding Your Best Starting Point in This Book
- •Conventions and Features in This Book
- •Conventions
- •Other Features
- •System Requirements
- •Code Samples
- •Installing the Code Samples
- •Using the Code Samples
- •Support for This Book
- •Questions and Comments
- •Beginning Programming with the Visual Studio 2008 Environment
- •Writing Your First Program
- •Using Namespaces
- •Creating a Graphical Application
- •Chapter 1 Quick Reference
- •Understanding Statements
- •Identifying Keywords
- •Using Variables
- •Naming Variables
- •Declaring Variables
- •Working with Primitive Data Types
- •Displaying Primitive Data Type Values
- •Using Arithmetic Operators
- •Operators and Types
- •Examining Arithmetic Operators
- •Controlling Precedence
- •Using Associativity to Evaluate Expressions
- •Associativity and the Assignment Operator
- •Incrementing and Decrementing Variables
- •Declaring Implicitly Typed Local Variables
- •Chapter 2 Quick Reference
- •Declaring Methods
- •Specifying the Method Declaration Syntax
- •Writing return Statements
- •Calling Methods
- •Specifying the Method Call Syntax
- •Applying Scope
- •Overloading Methods
- •Writing Methods
- •Chapter 3 Quick Reference
- •Declaring Boolean Variables
- •Using Boolean Operators
- •Understanding Equality and Relational Operators
- •Understanding Conditional Logical Operators
- •Summarizing Operator Precedence and Associativity
- •Using if Statements to Make Decisions
- •Understanding if Statement Syntax
- •Using Blocks to Group Statements
- •Cascading if Statements
- •Using switch Statements
- •Understanding switch Statement Syntax
- •Following the switch Statement Rules
- •Chapter 4 Quick Reference
- •Using Compound Assignment Operators
- •Writing while Statements
- •Writing for Statements
- •Understanding for Statement Scope
- •Writing do Statements
- •Chapter 5 Quick Reference
- •Coping with Errors
- •Trying Code and Catching Exceptions
- •Handling an Exception
- •Using Multiple catch Handlers
- •Catching Multiple Exceptions
- •Using Checked and Unchecked Integer Arithmetic
- •Writing Checked Statements
- •Writing Checked Expressions
- •Throwing Exceptions
- •Chapter 6 Quick Reference
- •The Purpose of Encapsulation
- •Controlling Accessibility
- •Working with Constructors
- •Overloading Constructors
- •Understanding static Methods and Data
- •Creating a Shared Field
- •Creating a static Field by Using the const Keyword
- •Chapter 7 Quick Reference
- •Copying Value Type Variables and Classes
- •Understanding Null Values and Nullable Types
- •Using Nullable Types
- •Understanding the Properties of Nullable Types
- •Using ref and out Parameters
- •Creating ref Parameters
- •Creating out Parameters
- •How Computer Memory Is Organized
- •Using the Stack and the Heap
- •The System.Object Class
- •Boxing
- •Unboxing
- •Casting Data Safely
- •The is Operator
- •The as Operator
- •Chapter 8 Quick Reference
- •Working with Enumerations
- •Declaring an Enumeration
- •Using an Enumeration
- •Choosing Enumeration Literal Values
- •Choosing an Enumeration’s Underlying Type
- •Working with Structures
- •Declaring a Structure
- •Understanding Structure and Class Differences
- •Declaring Structure Variables
- •Understanding Structure Initialization
- •Copying Structure Variables
- •Chapter 9 Quick Reference
- •What Is an Array?
- •Declaring Array Variables
- •Creating an Array Instance
- •Initializing Array Variables
- •Creating an Implicitly Typed Array
- •Accessing an Individual Array Element
- •Iterating Through an Array
- •Copying Arrays
- •What Are Collection Classes?
- •The ArrayList Collection Class
- •The Queue Collection Class
- •The Stack Collection Class
- •The Hashtable Collection Class
- •The SortedList Collection Class
- •Using Collection Initializers
- •Comparing Arrays and Collections
- •Using Collection Classes to Play Cards
- •Chapter 10 Quick Reference
- •Using Array Arguments
- •Declaring a params Array
- •Using params object[ ]
- •Using a params Array
- •Chapter 11 Quick Reference
- •What Is Inheritance?
- •Using Inheritance
- •Base Classes and Derived Classes
- •Calling Base Class Constructors
- •Assigning Classes
- •Declaring new Methods
- •Declaring Virtual Methods
- •Declaring override Methods
- •Understanding protected Access
- •Understanding Extension Methods
- •Chapter 12 Quick Reference
- •Understanding Interfaces
- •Interface Syntax
- •Interface Restrictions
- •Implementing an Interface
- •Referencing a Class Through Its Interface
- •Working with Multiple Interfaces
- •Abstract Classes
- •Abstract Methods
- •Sealed Classes
- •Sealed Methods
- •Implementing an Extensible Framework
- •Summarizing Keyword Combinations
- •Chapter 13 Quick Reference
- •The Life and Times of an Object
- •Writing Destructors
- •Why Use the Garbage Collector?
- •How Does the Garbage Collector Work?
- •Recommendations
- •Resource Management
- •Disposal Methods
- •Exception-Safe Disposal
- •The using Statement
- •Calling the Dispose Method from a Destructor
- •Making Code Exception-Safe
- •Chapter 14 Quick Reference
- •Implementing Encapsulation by Using Methods
- •What Are Properties?
- •Using Properties
- •Read-Only Properties
- •Write-Only Properties
- •Property Accessibility
- •Understanding the Property Restrictions
- •Declaring Interface Properties
- •Using Properties in a Windows Application
- •Generating Automatic Properties
- •Initializing Objects by Using Properties
- •Chapter 15 Quick Reference
- •What Is an Indexer?
- •An Example That Doesn’t Use Indexers
- •The Same Example Using Indexers
- •Understanding Indexer Accessors
- •Comparing Indexers and Arrays
- •Indexers in Interfaces
- •Using Indexers in a Windows Application
- •Chapter 16 Quick Reference
- •Declaring and Using Delegates
- •The Automated Factory Scenario
- •Implementing the Factory Without Using Delegates
- •Implementing the Factory by Using a Delegate
- •Using Delegates
- •Lambda Expressions and Delegates
- •Creating a Method Adapter
- •Using a Lambda Expression as an Adapter
- •The Form of Lambda Expressions
- •Declaring an Event
- •Subscribing to an Event
- •Unsubscribing from an Event
- •Raising an Event
- •Understanding WPF User Interface Events
- •Using Events
- •Chapter 17 Quick Reference
- •The Problem with objects
- •The Generics Solution
- •Generics vs. Generalized Classes
- •Generics and Constraints
- •Creating a Generic Class
- •The Theory of Binary Trees
- •Building a Binary Tree Class by Using Generics
- •Creating a Generic Method
- •Chapter 18 Quick Reference
- •Enumerating the Elements in a Collection
- •Manually Implementing an Enumerator
- •Implementing the IEnumerable Interface
- •Implementing an Enumerator by Using an Iterator
- •A Simple Iterator
- •Chapter 19 Quick Reference
- •What Is Language Integrated Query (LINQ)?
- •Using LINQ in a C# Application
- •Selecting Data
- •Filtering Data
- •Ordering, Grouping, and Aggregating Data
- •Joining Data
- •Using Query Operators
- •Querying Data in Tree<TItem> Objects
- •LINQ and Deferred Evaluation
- •Chapter 20 Quick Reference
- •Understanding Operators
- •Operator Constraints
- •Overloaded Operators
- •Creating Symmetric Operators
- •Understanding Compound Assignment
- •Declaring Increment and Decrement Operators
- •Implementing an Operator
- •Understanding Conversion Operators
- •Providing Built-In Conversions
- •Creating Symmetric Operators, Revisited
- •Adding an Implicit Conversion Operator
- •Chapter 21 Quick Reference
- •Creating a WPF Application
- •Creating a Windows Presentation Foundation Application
- •Adding Controls to the Form
- •Using WPF Controls
- •Changing Properties Dynamically
- •Handling Events in a WPF Form
- •Processing Events in Windows Forms
- •Chapter 22 Quick Reference
- •Menu Guidelines and Style
- •Menus and Menu Events
- •Creating a Menu
- •Handling Menu Events
- •Shortcut Menus
- •Creating Shortcut Menus
- •Windows Common Dialog Boxes
- •Using the SaveFileDialog Class
- •Chapter 23 Quick Reference
- •Validating Data
- •Strategies for Validating User Input
- •An Example—Customer Information Maintenance
- •Performing Validation by Using Data Binding
- •Changing the Point at Which Validation Occurs
- •Chapter 24 Quick Reference
- •Querying a Database by Using ADO.NET
- •The Northwind Database
- •Creating the Database
- •Using ADO.NET to Query Order Information
- •Querying a Database by Using DLINQ
- •Creating and Running a DLINQ Query
- •Deferred and Immediate Fetching
- •Joining Tables and Creating Relationships
- •Deferred and Immediate Fetching Revisited
- •Using DLINQ to Query Order Information
- •Chapter 25 Quick Reference
- •Using Data Binding with DLINQ
- •Using DLINQ to Modify Data
- •Updating Existing Data
- •Adding and Deleting Data
- •Chapter 26 Quick Reference
- •Understanding the Internet as an Infrastructure
- •Understanding Web Server Requests and Responses
- •Managing State
- •Understanding ASP.NET
- •Creating Web Applications with ASP.NET
- •Building an ASP.NET Application
- •Understanding Server Controls
- •Creating and Using a Theme
- •Chapter 27 Quick Reference
- •Comparing Server and Client Validations
- •Validating Data at the Web Server
- •Validating Data in the Web Browser
- •Implementing Client Validation
- •Chapter 28 Quick Reference
- •Managing Security
- •Understanding Forms-Based Security
- •Implementing Forms-Based Security
- •Querying and Displaying Data
- •Understanding the Web Forms GridView Control
- •Displaying Customer and Order History Information
- •Paging Data
- •Editing Data
- •Updating Rows Through a GridView Control
- •Navigating Between Forms
- •Chapter 29 Quick Reference
- •What Is a Web Service?
- •The Role of SOAP
- •What Is the Web Services Description Language?
- •Nonfunctional Requirements of Web Services
- •The Role of Windows Communication Foundation
- •Building a Web Service
- •Creating the ProductsService Web Service
- •Web Services, Clients, and Proxies
- •Talking SOAP: The Easy Way
- •Consuming the ProductsService Web Service
- •Chapter 30 Quick Reference
458 Part IV Working with Windows Applications
Handling Menu Events
The menu that you have built so far looks very pretty, but none of the items do anything when you click them. To make them functional, you have to write code to handle the various
menu events. Several different events can occur when a user selects a menu item. Some are more useful than others are. The most frequently used event is the Click event, which oc-
curs when the user clicks the menu item. You typically trap this event to perform the tasks associated with the menu item.
In the following exercise, you will learn more about menu events and how to process them. You will create Click events for the newMember and exit menu items.
The purpose of the New Member command is so that the user can enter the details of a new member. Therefore, until the user clicks New Member, all fields on the form should be disabled, as should the Save Member Details command. When the user clicks the New Member
command, you want to enable all the fields, reset the contents of the form so that the user can start adding information about a new member, and enable the Save Member Details
command.
Handle the and menu item events
1.In the XAML pane, click the definition of the firstName text box. In the Properties window, clear the IsEnabled property. (This action sets IsEnabled to False in the XAML definition.)
Repeat this process for the lastName, towerNames, isCaptain, hostMemberSince, yearsExperience, methods, add, and clear controls and for the saveMember menu item.
2.In the Design View window, in the XAML pane, begin entering the code shown here in bold type in the XAML description of the _New Member menu item:
<MenuItem Header=”_New Member” Click=”>
3.When the shortcut menu appears after you type the opening quotation mark, double-click the <New Event Handler> command.
Visual Studio generates an event method called newMember_Click and associates it with the Click event for the menu item.
Tip Always give a menu item a meaningful name when you define event methods for it. If you don’t, Visual Studio generates an event method called MenuItem_Click for the Click event. If you then create Click event methods for other menu items that also don’t have names, they are called MenuItem_Click_1, MenuItem_Click_2, and so on. If you have several
of these event methods, it can be difficult to work out which event method belongs to which menu item.
Chapter 23 Working with Menus and Dialog Boxes |
459 |
4.Switch to the Code and Text Editor window displaying the Window1.xaml.cs file. (On the View menu, click Code.)
The newMember_Click event method will have been added to the bottom of the Window1 class definition:
private void newMember_Click(object sender, RoutedEventArgs e)
{
}
5. Add the following statements shown in bold type to the memberFormClosing method:
private void newMember_Click(object sender, RoutedEventArgs e)
{
this.Reset(); saveMember.IsEnabled = true; firstName.IsEnabled = true; lastName.IsEnabled = true; towerNames.IsEnabled = true; isCaptain.IsEnabled = true; hostMemberSince.IsEnabled = true; yearsExperience.IsEnabled = true; methods.IsEnabled = true; add.IsEnabled = true; clear.IsEnabled = true;
}
This code calls the Reset method and then enables all the controls. If you remember from Chapter 22, the Reset method resets the controls on the form to their default values. (If you don’t recall how the Reset method works, scroll the Code and Text Editor
window to display the method and refresh your memory.)
Next, you need to create a Click event method for the Exit command. This method should cause the form to close.
6.Return to the Design View window displaying the Window1.xaml file. Use the technique you followed in step 2 to create a Click event method for the exit menu item called exit_Click.
7.Switch to the Code and Text Editor window. In the body of the exitClick method, type the statement shown in bold type in the following code:
private void newMember_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
The Close method of a form attempts to close the form. Remember that if the form intercepts the Closing event, it can prevent the form from closing. The Middleshire
Bell Ringers Association application does precisely this, and it asks the user if he or she wants to quit. If the user says no, the form does not close and the application continues to run.
460 Part IV Working with Windows Applications
The next step is to handle the saveMember menu item. When the user clicks this menu item, the data on the form should be saved to a file. For the time being, you will save the information to an ordinary text file called Members.txt in the current folder. Later, you will modify the code so that the user can select an alternative file name and location.
Handle the menu item event
1.Return to the Design View window displaying the Window1.xaml file. In the XAML pane, locate the definition of the saveMember menu item and use the <New Event Handler> command to specify a Click event method called saveMember_Click. (This is the default name generated by the <New Event Handler> command.)
2.In the Code and Text Editor window displaying the Window1.xaml.cs file, scroll to the top of the file and add the following using statement to the list:
using System.IO;
3.Locate the saveMember_Click event method at the end of the file. Add the following statements shown in bold type to the body of the method:
private void saveMember_Click(object sender, RoutedEventArgs e)
{
using (StreamWriter writer = new StreamWriter(“Members.txt”))
{
writer.WriteLine(“First Name: {0}”, firstName.Text); writer.WriteLine(“Last Name: {0}”, lastName.Text); writer.WriteLine(“Tower: {0}”, towerNames.Text); writer.WriteLine(“Captain: {0}”, isCaptain.IsChecked.ToString()); System.Windows.Forms.DateTimePicker memberDate =
hostMemberSince.Child as System.Windows.Forms.DateTimePicker; writer.WriteLine(“Member Since: {0}”, memberDate.Value.ToString()); writer.WriteLine(“Methods: “);
foreach (CheckBox cb in methods.Items)
{
if (cb.IsChecked.Value)
{
writer.WriteLine(cb.Content.ToString());
}
}
MessageBox.Show(“Member details saved”, “Saved”);
}
}
This block of code creates a StreamWriter object that the method uses for writing text to the Member.txt file. Using the StreamWriter class is very similar to displaying text in a console application by using the Console object—you can simply use the WriteLine
method.
Chapter 23 Working with Menus and Dialog Boxes |
461 |
When the details have all been written out, a message box is displayed giving the user some feedback (always a good idea).
4.The Add button and its associated event method are now obsolete, so in the Design View window delete the Add button. In the Code and Text Editor window, comment out the add_Click method.
5.In the newMember_Click method, comment out the following statement:
// add.IsEnabled = true;
The remaining menu item is the about menu item, which should display a dialog box providing information about the version of the application, the publisher, and any other useful information. You will add an event method to handle this event in the next exercise.
Handle the menu item event
1.On the Project menu, click Add Window.
2.In the Add New Item – BellRingers dialog box, in the Templates pane, click Window (WPF). In the Name text box, type About.xaml, and then click Add.
When you have added the appropriate controls, you will display this window when the user clicks the About Middleshire Bell Ringers command on the Help menu.
Note Visual Studio provides the About Box windows template. However, this template generates a Windows Forms window rather than a WPF window.
3.In the Design View window, click the About.xaml form. In the Properties window, change the Title property to About Middleshire Bell Ringers, set the Width property to 300, and set the Height property to 156. Set the ResizeMode property to NoResize to prevent the user from changing the size of the window.
4.In the Name box at the top of the Properties window, type AboutBellRingers.
5.Add two label controls and a button control to the form. In the XAML pane, modify the
properties of these three controls as shown here in bold type (feel free to change the text displayed by the buildDate label if you prefer):
<Window x:Class=”BellRingers.About” xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” Title=”About Middleshire Bell Ringers” Height=”156” Width=”300”
Name=”AboutBellRingers” ResizeMode=”NoResize”> <Grid>
<Label Margin=”80,20,0,0” Name=”version” Height=”30” VerticalAlignment=”Top” HorizontalAlignment=”Left” Width=”75”>Version 1.0</Label>
462 |
Part IV Working with Windows Applications |
<Label Margin=”80,50,0,0” Name=”buildDate” Height=”30” VerticalAlignment=”Top” HorizontalAlignment=”Left” Width=”160”>Build date: September 2007</Label>
<Button Margin=”100,85,0,0” Name=”ok” HorizontalAlignment=”Left” Width=”78” Height=”23” VerticalAlignment=”Top”>OK</Button>
</Grid>
</Window>
The completed form should look like this:
6.In the Design View window, double-click the OK button.
Visual Studio generates an event method for the Click event of the button and adds the ok_Click method to the About.xaml.cs file.
7.In the Code and Text Editor window displaying the About.xaml.cs file, add the statement shown in bold type to the ok_Click method:
private void ok_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
When the user clicks the OK button, the window will close.
8.Return to the Design View window displaying the Window1.xaml file. In the XAML pane, locate the definition of the about menu item and use the <New Event Handler> command to specify a Click event method called about_Click. (This is the default name generated by the <New Event Handler> command.)
9.In the Code and Text Editor window displaying the Window1.xaml.cs file, add the following statements shown in bold to the about_Click method:
private void about_Click(object sender, RoutedEventArgs e)
{
About aboutWindow = new About(); aboutWindow.ShowDialog();
}
This code creates a new instance of the About window and then calls the ShowDialog method to display it. The ShowDialog method does not return until the About window
closes (when the user clicks the OK button).
Chapter 23 Working with Menus and Dialog Boxes |
463 |
Test the menu events
1.On the Debug menu, click Start Without Debugging to build and run the application. Notice that all the fields on the form are disabled.
2.Click the File menu.
The Save Member Details command is disabled.
3.On the File menu, click New Member. The fields on the form are now available.
4.Input some details for a new member.
5.Click the File menu again.
The Save Member Details command is now available.
6.On the File menu, click Save Member Details.
After a short delay, the message “Member details saved” appears. Click OK in this message box.
7.Using Windows Explorer, move to the \Microsoft Press\Visual CSharp Step by Step\ Chapter 23\BellRingers\BellRingers\bin\Debug folder under your Documents folder.
You should see a file called Members.txt in this folder.
8.Double-click Members.txt to display its contents using Notepad. This file should contain the details of the new member.
9.Close Notepad, and return to the Middleshire Bell Ringers application.
10.On the Help menu, click About Middleshire Bell Ringers.
The About window appears. Notice that you cannot resize this window, and you cannot click any items on the Members form while the About window is still visible.
11.Click OK to return to the Members form.
12.On the File menu, click Exit.
The form tries to close. You are asked if you are sure you want to close the form. If you click No, the form remains open; if you click Yes, the form closes and the application finishes.
13.Click Yes to close the form.
