■ ■ ■
Programming with Windows Forms
Since the release of the .NET platform (circa 2001), the base class libraries have included a particular API named Windows Forms, represented primarily by the System.Windows.Forms.dll assembly. The Windows Forms toolkit provides the types necessary to build desktop graphical user interfaces (GUIs), create custom controls, manage resources (e.g., string tables and icons), and perform other desktop- centric programming tasks. In addition, a separate API named GDI+ (represented by the System.Drawing.dll assembly) provides additional types that allow programmers to generate 2D graphics, interact with networked printers, and manipulate image data. The Windows Forms (and GDI+) APIs remain alive and well within the .NET 4.0 platform, and they will exist within the base class library for quite some time (arguably forever). However, Microsoft has shipped a brand new GUI toolkit called Windows Presentation Foundation (WPF) since the release of .NET 3.0. As you saw in Chapters 27-31, WPF provides a massive amount of horsepower that you can use to build bleeding-edge user interfaces, and it has become the preferred desktop API for today’s .NET graphical user interfaces. The point of this appendix, however, is to provide a tour of the traditional Windows Forms API. One reason it is helpful to understand the original programming model: you can find many existing Windows Forms applications out there that will need to be maintained for some time to come. Also, many desktop GUIs simply might not require the horsepower offered by WPF. When you need to create more traditional business UIs that do not require an assortment of bells and whistles, the Windows Forms API can often fit the bill. In this appendix, you will learn the Windows Forms programming model, work with the integrated designers of Visual Studio 2010, experiment with numerous Windows Forms controls, and receive an overview of graphics programming using GDI+. You will also pull this information together in a cohesive whole by wrapping things up in a (semi-capable) painting application.
■ Note Here’s one proof that Windows Forms is not disappearing anytime soon: .NET 4.0 ships with a brand new Windows Forms assembly, System.Windows.Forms.DataVisualization.dll. You can use this library to incorporate charting functionality into your programs, complete with annotations; 3D rendering; and hit-testing support. This appendix will not cover this new .NET 4.0 Windows Forms API; however, you can look up the System.Windows.Forms.DataVisualization.Charting namespace if you want more information.
1511
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
The Windows Forms Namespaces The Windows Forms API consists of hundreds of types (e.g., classes, interfaces, structures, enums, and delegates), most of which are organized within various namespaces of the System.Windows.Forms.dll assembly. Figure A-1 shows these namespaces displayed in the Visual Studio 2010 object browser.
Figure A-1. The namespaces of System.Windows.Forms.dll
Far and away the most important Windows Forms namespace is System.Windows.Forms. At a high level, you can group the types within this namespace into the following broad categories: • Core infrastructure: These are types that represent the core operations of a Windows Forms program (e.g., Form and Application) and various types to facilitate interoperability with legacy ActiveX controls, as well as interoperability with new WPF custom controls. • Controls: These are types used to create graphical UIs (e.g., Button, MenuStrip, ProgressBar, and DataGridView), all of which derive from the Control base class. Controls are configurable at design time and are visible (by default) at runtime. • Components: These are types that do not derive from the Control base class, but still may provide visual features to a Windows Forms program (e.g., ToolTip and ErrorProvider). Many components (e.g., the Timer and System.ComponentModel.BackgroundWorker) are not visible at runtime, but can be configured visually at design time. • Common dialog boxes: Windows Forms provides several canned dialog boxes for common operations (e.g., OpenFileDialog, PrintDialog, and ColorDialog). As you would hope, you can certainly build your own custom dialog boxes if the standard dialog boxes do not suit your needs. Given that the total number of types within System.Windows.Forms is well over 100 strong, it would be redundant (not to mention a terrible waste of paper) to list every member of the Windows Forms
1512
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
family. As you work through this appendix, however, you will gain a firm foundation that you can build on. In any case, be sure to check out the .NET Framework 4.0 SDK documentation for additional details.
Building a Simple Windows Forms Application As you might expect, modern .NET IDEs (e.g., Visual Studio 2010, C# 2010 Express, and SharpDevelop) provide numerous form designers, visual editors, and integrated code-generation tools (wizards) to facilitate the construction of Windows Forms applications. These tools are extremely useful, but they can also hinder the process of learning Windows Forms, because these same tools tend to generate a good deal of boilerplate code that can obscure the core object model. Given this, you will create your first Windows Forms example using a Console Application project as a starting point. Begin by creating a Console Application named SimpleWinFormsApp. Next, use the Project ➤ Add Reference menu option to set a reference to the System.Windows.Forms.dll and System.Drawing.dll assemblies through the .NET tab of the resulting dialog box. Next, update your Program.cs file with the following code: using System; using System.Collections.Generic; using System.Linq; using System.Text;
// The minimum required windows forms namespaces. using System.Windows.Forms; namespace SimpleWinFormsApp { // This is the application object. class Program { static void Main(string[] args) { Application.Run(new MainWindow()); } }
// This is the main window. class MainWindow : Form {} }
■ Note When Visual Studio 2010 finds a class that extends System.Windows.Forms.Form, it attempts to open the related GUI designer (provided this class is the first class in the C# code file). Double-clicking the Program.cs file from the Solution Explorer opens the designer, but don’t do that yet! You will work with the Windows Forms designer in the next example; for now, be sure you right-click on the C# file containing your code within the Solution Explorer and select the View Code option.
1513
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
This code represents the absolute simplest Windows Forms application you can build. At a bare minimum, you need a class that extends the Form base class and a Main() method to call the static Application.Run() method (you can find more details on Form and Application later in this chapter). Running your application now reveals that you have a resizable, minimizable, maximizable, and closable topmost window (see Figure A-2).
Figure A-2. A simple Windows Forms application
■ Note When you run this program, you will notice a command prompt looming in the background of your topmost window. This is because, when you create a Console Application, the /target flag sent to the C# compiler defaults to /target:exe. You can change this to /target:winexe (preventing the display of the command prompt) by double-clicking the Properties icon in the Solution Explorer and changing the Output Type setting to Windows Application using the Application tab.
Granted, the current application is not especially exciting, but it does illustrate how simple a Windows Forms application can be. To spruce things up a bit, you can add a custom constructor to your MainWindow class, which allows the caller to set various properties on the window to be displayed:
// This is the main window. class MainWindow : Form { public MainWindow() {} public MainWindow(string title, int height, int width) { // Set various properties from the parent classes. Text = title; Width = width; Height = height;
1514
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
// Inherited method to center the form on the screen. CenterToScreen(); } }
You can now update the call to Application.Run(), as follows: static void Main(string[] args) { Application.Run(new MainWindow("My Window", 200, 300)); }
This is a step in the right direction, but any window worth its salt requires various user interface elements (e.g., menu systems, status bars, and buttons) to allow for input. To understand how a Form- derived type can contain such elements, you must understand the role of the Controls property and the underlying controls collection.
Populating the Controls Collection The System.Windows.Forms.Control base class (which is the inheritance chain of the Form type) defines a property named Controls. This property wraps a custom collection nested in the Control class named ControlsCollection. This collection (as the name suggests) references each UI element maintained by the derived type. Like other containers, this type supports several methods for inserting, removing, and finding a given UI widget (see Table A-1).
Table A-1. ControlCollection Members
Member Meaning in Life
Add() You use these members to insert a new Control-derived type (or array of AddRange() types) in the collection.
Clear() This member removes all entries in the collection.
Count This member returns the number of items in the collection.
Remove() You use these members to remove a control from the collection. RemoveAt()
When you wish to populate the UI of a Form-derived type, you typically follow a predictable series of steps: • Define a member variable of a given UI element within the Form-derived class. • Configure the look and feel of the UI element. • Add the UI element to the form’s ControlsCollection container using a call to Controls.Add().
1515
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Assume you wish to update your MainWindow class to support a File ➤ Exit menu system. Here are the relevant updates, with code analysis to follow:
class MainWindow : Form { // Members for a simple menu system. private MenuStrip mnuMainMenu = new MenuStrip(); private ToolStripMenuItem mnuFile = new ToolStripMenuItem(); private ToolStripMenuItem mnuFileExit = new ToolStripMenuItem();
public MainWindow(string title, int height, int width) { ... // Method to create the menu system. BuildMenuSystem(); }
private void BuildMenuSystem() { // Add the File menu item to the main menu. mnuFile.Text = "&File"; mnuMainMenu.Items.Add(mnuFile);
// Now add the Exit menu to the File menu. mnuFileExit.Text = "E&xit"; mnuFile.DropDownItems.Add(mnuFileExit); mnuFileExit.Click += (o, s) => Application.Exit();
// Finally, set the menu for this Form. Controls.Add(this.mnuMainMenu); MainMenuStrip = this.mnuMainMenu; } }
Notice that the MainWindow type now maintains three new member variables. The MenuStrip type represents the entirety of the menu system, while a given ToolStripMenuItem represents any topmost menu item (e.g., File) or submenu item (e.g., Exit) supported by the host. You configure the menu system within the BuildMenuSystem() helper function. Notice that the text of each ToolStripMenuItem is controlled through the Text property; each menu item has been assigned a string literal that contains an embedded ampersand symbol. As you might already know, this syntax sets the Alt key shortcut. Thus, selecting Alt+F activates the File menu, while selecting Alt+X activates the Exit menu. Also notice that the File ToolStripMenuItem object (mnuFile) adds subitems using the DropDownItems property. The MenuStrip object itself adds a topmost menu item using the Items property. Once you establish the menu system, you can add it to the controls collection (through the Controls property). Next, you assign your MenuStrip object to the form’s MainMenuStrip property. This step might seem redundant, but having a specific property such as MainMenuStrip makes it possible to dynamically establish which menu system to show a user. You might change the menu displayed based on user preferences or security settings. The only other point of interest is the fact that you handle the Click event of the File ➤ Exit menu; this helps you capture when the user selects this submenu. The Click event works in conjunction with a standard delegate type named System.EventHandler. This event can only call methods that take a
1516
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
System.Object as the first parameter and a System.EventArgs as the second. Here, you use a lambda expression to terminate the entire application with the static Application.Exit() method. Once you recompile and execute this application, you will find your simple window sports a custom menu system (see Figure A-3).
Figure A-3. A simple window, with a simple menu system
The Role of System.EventArgs and System.EventHandler System.EventHandler is one of many delegate types used within the Windows Forms (and ASP.NET) APIs during the event-handling process. As you have seen, this delegate can only point to methods where the first argument is of type System.Object, which is a reference to the object that sent the event. For example, assume you want to update the implementation of the lambda expression, as follows: mnuFileExit.Click += (o, s) => { MessageBox.Show(string.Format("{0} sent this event", o.ToString())); Application.Exit(); };
You can verify that the mnuFileExit type sent the event because the string is displayed within the message box:
"E&xit sent this event"
You might be wondering what purpose the second argument, System.EventArgs, serves. In reality, the System.EventArgs type brings little to the table because it simply extends Object and provides practically nothing by way of addition functionality: public class EventArgs { public static readonly EventArgs Empty; static EventArgs(); public EventArgs(); }
However, this type is useful in the overall scheme of .NET event handling because it is the parent to many (useful) derived types. For example, the MouseEventArgs type extends EventArgs to provide details regarding the current state of the mouse. KeyEventArgs also extends EventArgs to provide details of the
1517
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
state of the keyboard (such as which key was pressed); PaintEventArgs extends EventArgs to yield graphically relevant data; and so forth. You can also see numerous EventArgs descendents (and the delegates that make use of them) not only when working with Windows Forms, but when working with the WPF and ASP.NET APIs, as well. While you could continue to build more functionality into your MainWindow (e.g., status bars and dialog boxes) using a simple text editor, you would eventually end up with hand cramps because you have to author all the grungy control configuration logic manually. Thankfully, Visual Studio 2010 provides numerous integrated designers that take care of these details on your behalf. As you use these tools during the remainder of this chapter, always remember that these tools authoring everyday C# code; there is nothing magical about them whatsoever.
■ Source Code You can find the SimpleWinFormsApp project under the Appendix A subdirectory.
The Visual Studio Windows Forms Project Template When you wish to leverage the Windows Forms designer tools of Visual Studio 2010, your typically begin by selecting the Windows Forms Application project template using the File ➤ New Project menu option. To get comfortable with the core Windows Forms designer tools, create a new application named SimpleVSWinFormsApp (see Figure A-4).
Figure A-4. The Visual Studio Windows Forms Project Template
1518
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
The Visual Designer Surface Before you begin to build more interesting Windows applications, you will re-create the previous example leveraging the designer tools. Once you create a new Windows Forms project, you will notice that Visual Studio 2010 presents a designer surface to which you can drag-and-drop any number of controls. You can use this same designer to configure the initial size of the window simply by resizing the form itself using the supplied grab handles (see Figure A-5).
Figure A-5. The visual forms designer
When you wish to configure the look-and-feel of your window (as well as any control placed on a form designer), you do so using the Properties window. Similar to a Windows Presentation Foundation project, this window can be used to assign values to properties, as well as to establish event handlers for the currently selected item on the designer (you select a configuration using the drop-down list box mounted on the top of the Properties window). Currently, your form is devoid of content, so you see only a listing for the initial Form, which has been given a default name of Form1, as shown in the read-only Name property of Figure A-6.
Figure A-6. The Properties window for setting properties and handling events
1519
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
■ Note You can configure the Properties window to display its content by category or alphabetically using the first two buttons mounted beneath the drop-down list box. I’d suggest that you sort the items alphabetically to find a given property or event quickly.
The next designer element to be aware of is the Solution Explorer window. All Visual Studio 2010 projects support this window, but it is especially helpful when building Windows Forms applications to be able to (1) change the name of the file and related class for any window quickly, and (2) view the file that contains the designer-maintained code (you’ll learn more information on this tidbit in just a moment). For now, right-click the Form1.cs icon and select the Rename option. Name this initial window to something more fitting: MainWindow.cs. The IDE will ask you if you wish to change the name of your initial class; it’s fine to do this.
Dissecting the Initial Form Before you build your menu system, you need to examine exactly what Visual Studio 2010 has created by default. Right-click the MainWindow.cs icon from the Solution Explorer window and select View Code. Notice that the form has been defined as a partial type, which allows a single type to be defined within multiple code files (see Chapter 5 for more information about this). Also, note that the form’s constructor makes a call to a method named InitializeComponent() and your type is-a Form:
namespace SimpleVSWinFormsApp { public partial class MainWindow : Form { public MainWindow() { InitializeComponent(); } } }
As you might be expecting, InitializeComponent() is defined in a separate file that completes the partial class definition. As a naming convention, this file always ends in .Designer.cs, preceded by the name of the related C# file containing the Form-derived type. Using the Solution Explorer window, open your MainWindow.Designer.cs file. Now, ponder the following code (this snippet strips out the code comments for simplicity; your code might differ slightly, based on the configurations you did in the Properties window):
partial class MainWindow { private System.ComponentModel.IContainer components = null;
protected override void Dispose(bool disposing) { if (disposing && (components != null)) {
1520
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
components.Dispose(); } base.Dispose(disposing); }
private void InitializeComponent() { this.SuspendLayout(); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(422, 114); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout(false); } }
The IContainer member variable and Dispose() methods are little more than infrastructure used by the Visual Studio designer tools. However, notice that the InitializeComponent() is present and accounted for. Not only is this method invoked by a form’s constructor at runtime, Visual Studio makes use of this same method at design time to render correctly the UI seen on the Forms designer. To see this in action, change the value assigned to the Text property of the window to "My Main Window". Once you activate the designer, the form’s caption will update accordingly. When you use the visual design tools (e.g., the Properties window or the form designer), the IDE updates InitializeComponent() automatically. To illustrate this aspect of the Windows Forms designer tools, ensure that the Forms designer is the active window within the IDE and find the Opacity property listed in the Properties window. Change this value to 0.8 (80%); this gives your window a slightly transparent look-and-feel the next time you compile and run your program. Once you make this change, reexamine the implementation of InitializeComponent(): private void InitializeComponent() { ... this.Opacity = 0.8; }
For all practical purposes, you should ignore the *.Designer.cs files and allow the IDE to maintain them on your behalf when you build a Windows Forms application using Visual Studio. If you were to author syntactically (or logically) incorrect code within InitializeComponent(), you might break the designer. Also, Visual Studio often reformats this method at design time. Thus, if you were to add custom code to InitializeComponent(), the IDE might delete it! In any case, remember that each window of a Windows Forms application is composed using partial classes.
Dissecting the Program Class Beyond providing implementation code for an initial Form-derived type, the Windows Application project types also provide a static class (named Program) that defines your program’s entry point, Main(): static class Program {
1521
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
[STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainWindow()); } }
The Main() method invokes Application.Run() and a few other calls on the Application type to establish some basic rendering options. Last but not least, note that the Main() method has been adorned with the [STAThread] attribute. This informs the runtime that if this thread happens to create any classic COM objects (including legacy ActiveX UI controls) during its lifetime, the runtime must place these objects in a COM-maintained area termed the single-threaded apartment. In a nutshell, this ensures that the COM objects are thread-safe, even if the author of a given COM object did not explicitly include code to ensure this is the case.
Visually Building a Menu System To wrap up this look at the Windows Forms visual designer tools and move on to some more illustrative examples, activate the Forms designer window, locate the Toolbox window of Visual Studio 2010, and find the MenuStrip control within the Menus & Toolbars node (see Figure A-7).
Figure A-7. Windows Forms controls you can add to your designer surface
Drag a MenuStrip control onto the top of your Forms designer. Notice that Visual Studio responds by activating the menu editor. If you look closely at this editor, you will notice a small triangle on the top- right of the control. Clicking this icon opens a context-sensitive inline editor that allows you to make numerous property settings at once (be aware that many Windows Forms controls have similar inline editors). For example, click the Insert Standard Items option, as shown in Figure A-8.
1522
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Figure A-8. The inline menu editor
In this example, Visual Studio was kind enough to establish an entire menu system on your behalf. Now open your designer-maintained file (MainWindow.Designer.cs) and note the numerous lines of code added to InitializeComponent(), as well as several new member variables that represent your menu system (designer tools are good things!). Finally, flip back to the designer and undo the previous operation by clicking the Ctrl+Z keyboard combination. This brings you back to the initial menu editor and removes the generated code. Using the menu designer, type in a topmost File menu item, followed by an Exit submenu (see Figure A-9).
Figure A-9. Manually building our menu system
If you take a look at InitializeComponent(), you will find the same sort of code you authored by hand in the first example of this chapter. To complete this exercise, flip back to the Forms designer and click the lightning bolt button mounted on the Properties window. This shows you all of the events you can handle for the selected control. Make sure you select the Exit menu (named exitToolStripMenuItem by default), then locate the Click event (see Figure A-10).
1523
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Figure A-10. Establishing Events with the IDE
At this point, you can enter the name of the method to be called when the item is clicked; or, if you feel lazy at this point, you can double-click the event listed in the Properties window. This lets the IDE pick the name of the event handler on your behalf (which follows the pattern, NameOfControl_NameOfEvent()).In either case, the IDE will create stub code, and you can fill in the implementation details:
public partial class MainWindow : Form { public MainWindow() { InitializeComponent(); CenterToScreen(); } private void exitToolStripMenuItem_Click(object sender, EventArgs e) { Application.Exit(); } }
If you so desire, you can take a quick peek at InitializeComponent(), where the necessary event riggings have also been accounted for:
this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
At this point, you probably feel more comfortable moving around the IDE when building Windows Forms applications. While there are obviously many additional shortcuts, editors, and integrated code wizards, this information is more than enough for you to press onward.
1524
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
The Anatomy of a Form So far you have examined how to build simple Windows Forms applications with (and without) the aid of Visual Studio; now it’s time to examine the Form type in greater detail. In the world of Windows Forms, the Form type represents any window in the application, including the topmost main windows, child windows of a multiple document interface (MDI) application, as well as modal and modeless dialog boxes. As Figure A-11 shows, the Form type gathers a good deal of functionality from its parent classes and the numerous interfaces it implements.
Figure A-11. The inheritance chain of System.Windows.Forms.Form
Table A-2 offers a high-level look at each parent class in the Form’s inheritance chain.
Table A-2. Base Classes in the Form Inheritance Chain
Parent Class Meaning in Life
System.Object Like any class in .NET, a Form is-a object.
System.MarshalByRefObject Types deriving from this class are accessed remotely through a reference to (not a local copy of) the remote type.
System.ComponentModel. This class provides a default implementation of the IComponent Component interface. In the .NET universe, a component is a type that supports design-time editing, but it is not necessarily visible at runtime.
1525
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Table A-2. Base Classes in the Form Inheritance Chain (continued)
Parent Class Meaning in Life
System.Windows.Forms.Control This class defines common UI members for all Windows Forms UI controls, including the Form type itself.
System.Windows.Forms. This class defines support for horizontal and vertical scrollbars, as ScrollableControl well as members, which allow you to manage the viewport shown within the scrollable region.
System.Windows.Forms. This class provides focus-management functionality for controls ContainerControl that can function as a container for other controls.
System.Windows.Forms.Form This class represents any custom form, MDI child, or dialog box.
Although the complete derivation of a Form type involves numerous base classes and interfaces, you should keep in mind that you are not required to learn the role of each and every member of each and every parent class or implemented interface to be a proficient Windows Forms developer. In fact, you can easily set the majority of the members (specifically, properties and events) you use on a daily basis using the Visual Studio 2010 Properties window. That said, it is important that you understand the functionality provided by the Control and Form parent classes.
The Functionality of the Control Class The System.Windows.Forms.Control class establishes the common behaviors required by any GUI type. The core members of Control allow you to configure the size and position of a control, capture keyboard and mouse input, get or set the focus/visibility of a member, and so forth. Table A-3 defines some properties of interest, which are grouped by related functionality.
Table A-3. Core Properties of the Control Type
Property Meaning in Life
BackColor These properties define the core UI of the control (e.g., colors, font for text, ForeColor and the mouse cursor to display when the mouse is over the widget). BackgroundImage Font Cursor
Anchor These properties control how the control should be positioned within the Dock container. AutoSize
1526
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Table A-3. Core Properties of the Control Type (continued)
Property Meaning in Life
Top These properties specify the current dimensions of the control. Left Bottom Right Bounds ClientRectangle Height Width
Enabled These properties encapsulate a Boolean that specifies the state of the Focused current control. Visible
ModifierKeys This static property checks the current state of the modifier keys (e.g., Shift, Ctrl, and Alt) and returns the state in a Keys type.
MouseButtons This static property checks the current state of the mouse buttons (left, right, and middle mouse buttons) and returns this state in a MouseButtons type.
TabIndex You use these properties to configure the tab order of the control. TabStop
Opacity This property determines the opacity of the control (0.0 is completely transparent; 1.0 is completely opaque).
Text This property indicates the string data associated with this control.
Controls This property allows you to access a strongly typed collection (e.g., ControlsCollection) that contains any child controls within the current control.
As you might guess, the Control class also defines a number of events that allow you to intercept mouse, keyboard, painting, and drag-and-drop activities, among other things. Table A-4 lists some events of interest, grouping them by related functionality.
1527
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Table A-4. Events of the Control Type
Event Meaning in Life
Click These events that let you interact with the mouse. DoubleClick MouseEnter MouseLeave MouseDown MouseUp MouseMove MouseHover MouseWheel
KeyPress These events let you interact with the keyboard. KeyUp KeyDown
DragDrop You use these events to monitor drag-and-drop activity. DragEnter DragLeave DragOver
Paint This event lets you to interact with the graphical rendering services of GDI+.
Finally, the Control base class also defines a several methods that allow you to interact with any Control-derived type. As you examine the methods of the Control type, notice that a many of them have an On prefix, followed by the name of a specific event (e.g., OnMouseMove, OnKeyUp, and OnPaint). Each of these On-prefixed virtual methods is the default event handler for its respective event. If you override any of these virtual members, you gain the ability to perform any necessary pre- or post-processing of the event before (or after) invoking the parent’s default implementation:
public partial class MainWindow : Form { protected override void OnMouseDown(MouseEventArgs e) { // Add custom code for MouseDown event here.
// Call parent implementation when finished. base.OnMouseDown(e); } }
This can be helpful in some circumstances (especially if you want to build a custom control that derives from a standard control), but you will often handle events using the standard C# event syntax (in fact, this is the default behavior of the Visual Studio designers). When you handle events in this manner, the framework calls your custom event handler once the parent’s implementation has completed. For example, this code lets you manually handle the MouseDown event:
1528
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
public partial class MainWindow : Form { public MainWindow() { ... MouseDown += new MouseEventHandler(MainWindow_MouseDown); }
private void MainWindow_MouseDown(object sender, MouseEventArgs e) { // Add code for MouseDown event. } }
You should also be aware of a few other methods, in addition to the just described OnXXX() methods: • Hide(): Hides the control and sets the Visible property to false. • Show(): Shows the control and sets the Visible property to true. • Invalidate(): Forces the control to redraw itself by sending a Paint event (you learn more about graphical rendering using GDI+ later in this chapter).
The Functionality of the Form Class The Form class is typically (but not necessarily) the direct base class for your custom Form types. In addition to the large set of members inherited from the Control, ScrollableControl, and ContainerControl classes, the Form type adds additional functionality in particular to main windows, MDI child windows, and dialog boxes. Let’s start with the core properties in Table A-5.
Table A-5. Properties of the Form Type
Property Meaning in Life
AcceptButton Gets or sets the button on the form that is clicked when the user presses the Enter key.
ActiveMdiChild Used within the context of an MDI application. IsMdiChild IsMdiContainer
CancelButton Gets or sets the button control that will be clicked when the user presses the Esc key.
ControlBox Gets or sets a value that indicates whether the form has a control box (e.g., the minimize, maximize, and close icons in the upper right of a window).
FormBorderStyle Gets or sets the border style of the form. You use this in conjunction with the FormBorderStyle enumeration.
1529
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Table A-5. Properties of the Form Type (continued)
Property Meaning in Life
Menu Gets or sets the menu to dock on the form.
MaximizeBox Used to determine whether this form will enable the maximize and MinimizeBox minimize boxes.
ShowInTaskbar Determines whether this form will be seen on the Windows taskbar.
StartPosition Gets or sets the starting position of the form at runtime, as specified by the FormStartPosition enumeration.
WindowState Configures how the form is to be displayed on startup. You use this in conjunction with the FormWindowState enumeration.
In addition to numerous On-prefixed default event handlers, Table A-6 provides a list of some core methods defined by the Form type.
Table A-6. Key Methods of the Form Type
Method Meaning in Life
Activate() Activates a given form and gives it focus.
Close() Closes the current form.
CenterToScreen() Places the form in the center of the screen
LayoutMdi() Arranges each child form (as specified by the MdiLayout enumeration) within the parent form.
Show() Displays a form as a modeless window.
ShowDialog() Displays a form as a modal dialog box.
Finally, the Form class defines a number of events, many of which fire during the form’s lifetime (see Table A-7).
1530
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Table A-7. Select Events of the Form Type
Event Meaning in Life
Activated This event occurs whenever the form is activated, which means that the form has been given the current focus on the desktop.
FormClosed You use these events to determine when the form is about to close or has closed. FormClosing
Deactivate This event occurs whenever the form is deactivated, which means the form has lost the current focus on the desktop.
Load This event occurs after the form has been allocated into memory, but is not yet visible on the screen.
MdiChildActive This event is sent when a child window is activated.
The Life Cycle of a Form Type If you have programmed user interfaces using GUI toolkits such as Java Swing, Mac OS X Cocoa, or WPF, you know that window types have many events that fire during their lifetime. The same holds true for Windows Forms. As you have seen, the life of a form begins when the class constructor is called prior to being passed into the Application.Run() method. Once the object has been allocated on the managed heap, the framework fires the Load event. Within a Load event handler, you are free to configure the look-and-feel of the Form, prepare any contained child controls (e.g., ListBoxes and TreeViews), or allocate resources used during the Form’s operation (e.g., database connections and proxies to remote objects). Once the Load event fires, the next event to fire is Activated. This event fires when the form receives the focus as the active window on the desktop. The logical counterpart to the Activated event is (of course) Deactivate, which fires when the form loses the focus as the active window. As you can guess, the Activated and Deactivate events can fire numerous times over the life of a given Form object as the user navigates between active windows and applications. Two events fire when the user chooses to close a given form: FormClosing and FormClosed. The FormClosing event is fired first and is an ideal place to prompt the end user with the much hated (but useful) message: “Are you sure you wish to close this application?” This step gives the user a chance to save any application-centric data before terminating the program. The FormClosing event works in conjunction with the FormClosingEventHandler delegate. If you set the FormClosingEventArgs.Cancel property to true, you prevent the window from being destroyed and instruct it to return to normal operation. If you set FormClosingEventArgs.Cancel to false, the FormClosed event fires, and the Windows Forms application exits, which unloads the AppDomain and terminates the process. This snippet updates your form’s constructor and handles the Load, Activated, Deactivate, FormClosing, and FormClosed events (you might recall from Chapter 11 that the IDE will autogenerate the correct delegate and event handler when you press the Tab key twice after typing +=): public MainWindow() {
1531
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
InitializeComponent();
// Handle various lifetime events. FormClosing += new FormClosingEventHandler(MainWindow_Closing); Load += new EventHandler(MainWindow_Load); FormClosed += new FormClosedEventHandler(MainWindow_Closed); Activated += new EventHandler(MainWindow_Activated); Deactivate += new EventHandler(MainWindow_Deactivate); } Within the Load, FormClosed, Activated, and Deactivate event handlers, you must update the value of a new Form-level string member variable (named lifeTimeInfo) with a simple message that displays the name of the event that has just been intercepted. Begin by adding this member to your Form derived class:
public partial class MainWindow : Form { private string lifeTimeInfo = ""; ... } The next step is to implement the event handlers. Notice that you display the value of the lifeTimeInfo string within a message box in the FormClosed event handler:
private void MainWindow_Load(object sender, System.EventArgs e) { lifeTimeInfo += "Load event\n"; }
private void MainWindow_Activated(object sender, System.EventArgs e) { lifeTimeInfo += "Activate event\n"; }
private void MainWindow_Deactivate(object sender, System.EventArgs e) { lifeTimeInfo += "Deactivate event\n"; }
private void MainWindow_Closed(object sender, FormClosedEventArgs e) { lifeTimeInfo += "FormClosed event\n"; MessageBox.Show(lifeTimeInfo); } Within the FormClosing event handler, you prompt the user to ensure that she wishes to terminate the application using the incoming FormClosingEventArgs. In the following code, the MessageBox.Show() method returns a DialogResult type that contains a value representing which button has been selected by the end user. Here, you craft a message box that displays Yes and No buttons; therefore, you want to discover whether the return value from Show() is DialogResult.No:
private void MainWindow_Closing(object sender, FormClosingEventArgs e) {
1532
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
lifeTimeInfo += "FormClosing event\n";
// Show a message box with Yes and No buttons. DialogResult dr = MessageBox.Show("Do you REALLY want to close this app?", "Closing event!", MessageBoxButtons.YesNo);
// Which button was clicked? if (dr == DialogResult.No) e.Cancel = true; else e.Cancel = false; }
Let’s make one final adjustment. Currently, the File ➤ Exit menu destroys the entire application, which is a bit aggressive. More often, the File ➤ Exit handler of a top-most window calls the inherited Close() method, which fires the close-centric events and then tears down the application: private void exitToolStripMenuItem_Click(object sender, EventArgs e) { // Application.Exit(); Close(); }
Now run your application and shift the form into and out of focus a few times (to trigger the Activated and Deactivate events). When you eventually shut down the application, you will see a message box that looks something like the message shown in Figure A-12.
Figure A-12. The life and times of a Form-derived type
■ Source Code You can find the SimpleVSWinFormsApp project under the Appendix A subdirectory.
1533
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Responding to Mouse and Keyboard Activity You might recall that the Control parent class defines a set of events that allow you to monitor mouse and keyboard activity in a variety of manners. To check this out firsthand, create a new Windows Forms Application project named MouseAndKeyboardEventsApp, rename the initial form to MainWindow.cs (using the Solution Explorer), and handle the MouseMove event using the Properties window. These steps generate the following event handler:
public partial class MainWindow : Form { public MainWindow() { InitializeComponent(); }
// Generated via the Properties window. private void MainWindow_MouseMove(object sender, MouseEventArgs e) { } }
The MouseMove event works in conjunction with the System.Windows.Forms.MouseEventHandler delegate. This delegate can only call methods where the first parameter is a System.Object, while the second is of type MouseEventArgs. This type contains various members that provide detailed information about the state of the event when mouse-centric events occur:
public class MouseEventArgs : EventArgs { public MouseEventArgs(MouseButtons button, int clicks, int x, int y, int delta);
public MouseButtons Button { get; } public int Clicks { get; } public int Delta { get; } public Point Location { get; } public int X { get; } public int Y { get; } }
Most of the public properties are self-explanatory, but Table A-8 provides more specific details.
Table A-8. Properties of the MouseEventArgs Type
Property Meaning in Life
Button Gets which mouse button was pressed, as defined by the MouseButtons enumeration.
Clicks Gets the number of times the mouse button was pressed and released.
1534
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Table A-8. Properties of the MouseEventArgs Type (continued)
Property Meaning in Life
Delta Gets a signed count of the number of detents (which represents a single notch of the mouse wheel) for the current mouse rotation.
Location Returns a Point that contains the current X and Y location of the mouse.
X Gets the x-coordinate of a mouse click.
Y Gets the y-coordinate of a mouse click.
Now it’s time to implement your MouseMove handler to display the current X- and Y-position of the mouse on the Form’s caption; you do this using the Location property: private void MainWindow_MouseMove(object sender, MouseEventArgs e) { Text = string.Format("Mouse Position: {0}", e.Location); }
When you run the application and move the mouse over the window, you find the position displayed on the title area of your MainWindow type (see Figure A-13).
Figure A-13. Intercepting mouse movements
Determining Which Mouse Button Was Clicked Another common mouse-centric detail to attend to is determining which button has been clicked when a MouseUp, MouseDown, MouseClick, or MouseDoubleClick event occurs. When you wish to determine exactly which button was clicked (whether left, right, or middle), you need to examine the Button property of the MouseEventArgs class. The value of the Button property is constrained by the related MouseButtons enumeration: public enum MouseButtons { Left,
1535
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Middle, None, Right, XButton1, XButton2 }
■ Note The XButton1 and XButton2 values allow you to capture forward and backwards navigation buttons that are supported on many mouse-controller devices.
You can see this in action by handling the MouseDown event on your MainWindow type using the Properties window. The following MouseDown event handler displays which mouse button was clicked inside a message box:
private void MainWindow_MouseDown (object sender, MouseEventArgs e) { // Which mouse button was clicked? if(e.Button == MouseButtons.Left) MessageBox.Show("Left click!"); if(e.Button == MouseButtons.Right) MessageBox.Show("Right click!"); if (e.Button == MouseButtons.Middle) MessageBox.Show("Middle click!"); }
Determining Which Key Was Pressed Windows applications typically define numerous input controls (e.g., the TextBox) where the user can enter information using the keyword. When you capture keyboard input in this manner, you do not need to handle keyboard events explicitly because you can extract the textual data from the control using various properties (e.g., the Text property of the TextBox type). However, if you need to monitor keyboard input for more exotic purposes (e.g., filtering keystrokes on a control or capturing keypresses on the form itself), the base class libraries provide the KeyUp and KeyDown events. These events work in conjunction with the KeyEventHandler delegate, which can point to any method taking an object as the first parameter and KeyEventArgs as the second. You define this type like this:
public class KeyEventArgs : EventArgs { public KeyEventArgs(Keys keyData);
public virtual bool Alt { get; } public bool Control { get; } public bool Handled { get; set; } public Keys KeyCode { get; } public Keys KeyData { get; }
1536
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
public int KeyValue { get; } public Keys Modifiers { get; } public virtual bool Shift { get; } public bool SuppressKeyPress { get; set; } }
Table A-9 documents some of the more interesting properties supported by KeyEventArgs.
Table A-9. Properties of the KeyEventArgs Type
Property Meaning in Life
Alt Gets a value that indicates whether the Alt key was pressed.
Control Gets a value that indicates whether the Ctrl key was pressed.
Handled Gets or sets a value that indicates whether the event was fully handled in your handler.
KeyCode Gets the keyboard code for a KeyDown or KeyUp event.
Modifiers Indicates which modifier keys (e.g., Ctrl, Shift, and/or Alt) were pressed.
Shift Gets a value that indicates whether the Shift key was pressed.
You can see this in action by handling the KeyDown event as follows: private void MainWindow_KeyDown(object sender, KeyEventArgs e) { Text = string.Format("Key Pressed: {0} Modifiers: {1}", e.KeyCode.ToString(), e.Modifiers.ToString()); }
Now compile and run your program. You should be able to determine which mouse button was clicked, as well as which keyboard key was pressed. For example, Figure A-14 shows the result of pressing the Ctrl and Shift keys simultaneously.
Figure A-14. Intercepting keyboard activity
1537
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
■ Source Code You can find the MouseAndKeyboardEventsApp project under the Appendix A subdirectory.
Designing Dialog Boxes Within a graphical user interface program, dialog boxes tend to be the primary way to capture user input for use within the application itself. Unlike other GUI APIs you might have used previously, there Windows Forms has no Dialog base class. Rather, dialog boxes under Windows Forms are simply types that derive from the Form class. In addition, many dialog boxes are intended to be nonsizable; therefore, you typically want to set the FormBorderStyle property to FormBorderStyle.FixedDialog. Also, dialog boxes typically set the MinimizeBox and MaximizeBox properties to false. In this way, the dialog box is configured to be a fixed constant. Finally, if you set the ShowInTaskbar property to false, you will prevent the form from being visible in the Windows taskbar. Let’s look at how to build and manipulate dialog boxes. Begin by creating a new Windows Forms Application project named CarOrderApp and rename the initial Form1.cs file to MainWindow.cs using Solution Explorer. Next, use the Forms designer to create a simple File ➤ Exit menu, as well as a Tool ➤ Order Automobile... menu item (remember: you create a menu by dragging a MenuStrip from the Toolbox and then configuring the menu items in the designer window). Once you do this, handle the Click event for the Exit and Order Automobile submenus using the Properties window. You implement the File ➤ Exit menu handler so it terminates the application with a call to Close():
private void exitToolStripMenuItem_Click(object sender, EventArgs e) { Close(); }
Now use the Project menu of Visual Studio to select the Add Windows Forms menu option and name your new form OrderAutoDialog.cs (see Figure A-15). For this example, design a dialog box that has the expected OK and Cancel buttons (named btnOK and btnCancel, respectively), as well as three TextBox controls named txtMake, txtColor, and txtPrice. Now use the Properties window to finalize the design of your dialog box, as follows: • Set the FormBorderStyle property to FixedDialog. • Set the MinimizeBox and MaximizeBox properties to false. • Set the StartPosition property to CenterParent. • Set the ShowInTaskbar property to false.
1538
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Figure A-15. Inserting new dialog boxes using Visual Studio
The DialogResult Property Finally, select the OK button and use the Properties window to set the DialogResult property to OK. Similarly, you can set the DialogResult property of the Cancel button to (you guessed it) Cancel. As you will see in a moment, the DialogResult property is quite useful because it enables the launching form to determine quickly which button the user has clicked; this enables you to take the appropriate action. You can set the DialogResult property to any value from the related DialogResult enumeration: public enum DialogResult { Abort, Cancel, Ignore, No, None, OK, Retry, Yes }
Figure A-16 shows one possible design of your dialog box; it even adds in a few descriptive Label controls.
1539
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Figure A-16. The OrderAutoDialog type
Configuring the Tab Order You have created a somewhat interesting dialog box; the next step is formalize the tab order. As you might know, users expect to be able to shift focus using the Tab key when a form contains multiple GUI widgets. Configuring the tab order for your set of controls requires that you understand two key properties: TabStop and TabIndex. You can set the TabStop property to true or false, based on whether or not you wish this GUI item to be reachable using the Tab key. Assuming that you set the TabStop property to true for a given control, you can use the TabOrder property to establish the order of activation in the tabbing sequence (which is zero-based), as in this example:
// Configure tabbing properties. txtMake.TabIndex = 0; txtMake.TabStop = true;
The Tab Order Wizard You can set the TabStop and TabIndex manually using the Properties window; however, the Visual Studio 2010 IDE supplies a Tab Order Wizard that you can access by choosing View ➤ Tab Order (be aware that you will not find this menu option unless the Forms designer is active). Once activated, your design-time form displays the current TabIndex value for each widget. To change these values, click each item in the order you prefer the controls to tab (see Figure A-17).
1540
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Figure A-17. The Tab Order Wizard
You can exit the Tab Order Wizard by pressing the Esc key.
Setting the Form’s Default Input Button Many user-input forms (especially dialog boxes) have a particular button that automatically responds to the user pressing the Enter key. Now assume that you want the Click event handler for btnOK invoked when the user presses the Enter key. Doing so is as simple as setting the form’s AcceptButton property as follows (you can establish this same setting using the Properties window): public partial class OrderAutoDialog : Form { public OrderAutoDialog() { InitializeComponent();
// When the Enter key is pressed, it is as if // the user clicked the btnOK button. this.AcceptButton = btnOK; } }
■ Note Some forms require the ability to simulate clicking the form’s Cancel button when the user presses the Esc key. You can accomplish this by assigning the CancelButton property of the Form to the Button object that represents the clicking of the Cancel button.
1541
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Displaying Dialog Boxes When you wish to display a dialog box, you must first decide whether you wish to launch the dialog box in a modal or modeless fashion. As you might know, modal dialog boxes must be dismissed by the user before he can return to the window that launched the dialog box in the first place; for example, most About boxes are modal in nature. To show a modal dialog box, call ShowDialog() off your dialog box object. On the other hand, you can display a modeless dialog box by calling Show(), which allows the user to switch focus between the dialog box and the main window (e.g., a Find/Replace dialog box). For this example, you want to update the Tools ➤ Order Automobile... menu handler of the MainWindow type to show the OrderAutoDialog object in a modal manner. Consider the following initial code:
private void orderAutomobileToolStripMenuItem_Click(object sender, EventArgs e) { // Create your dialog object. OrderAutoDialog dlg = new OrderAutoDialog();
// Show as modal dialog box, and figure out which button // was clicked using the DialogResult return value. if (dlg.ShowDialog() == DialogResult.OK) { // They clicked OK, so do something... } }
■ Note You can optionally call the ShowDialog() and Show() methods by specifying an object that represents the owner of the dialog box (which for the form loading the dialog box would be represented by this). Specifying the owner of a dialog box establishes the z-ordering of the form types and also ensures (in the case of a modeless dialog box) that all owned windows are also disposed of when the main window is destroyed.
Be aware that when you create an instance of a Form-derived type (OrderAutoDialog in this case), the dialog box is not visible on the screen, but simply allocated into memory. It is not until you call Show() or ShowDialog() that the form becomes visible. Also, notice that ShowDialog() returns the DialogResult value that has been assigned to the button (the Show() method simply returns void). Once ShowDialog() returns, the form is no longer visible on the screen, but is still in memory. This means you can extract the values in each TextBox. However, you will receive compiler errors if you attempt to compile the following code:
private void orderAutomobileToolStripMenuItem_Click(object sender, EventArgs e) { // Create your dialog object. OrderAutoDialog dlg = new OrderAutoDialog();
// Show as modal dialog box, and figure out which button
1542
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
// was clicked using the DialogResult return value. if (dlg.ShowDialog() == DialogResult.OK) { // Get values in each text box? Compiler errors! string orderInfo = string.Format("Make: {0}, Color: {1}, Cost: {2}", dlg.txtMake.Text, dlg.txtColor.Text, dlg.txtPrice.Text); MessageBox.Show(orderInfo, "Information about your order!"); } }
The reason you get compiler errors is that Visual Studio 2010 declares the controls you add to the Forms designer as private member variables of the class! You can verify this fact by opening the OrderAutoDialog.Designer.cs file. While a prim-and-proper dialog box might preserve encapsulation by adding public properties to get and set the values within these text boxes, you can take a shortcut and redefine them by using the public keyword. To do so, select each TextBox on the designer, and then set the Modifiers property of the control to Public using the Properties window. This changes the underlying designer code: partial class OrderAutoDialog { ... // Form member variables are defined within the designer-maintained file. public System.Windows.Forms.TextBox txtMake; public System.Windows.Forms.TextBox txtColor; public System.Windows.Forms.TextBox txtPrice; }
At this point, you can compile and run your application. Once you launch your dialog box, you should be able to see the input data displayed within a message box (provided you click the OK button).
Understanding Form Inheritance So far, each one of your custom windows/dialog boxes in this chapter has derived directly from System.Windows.Forms.Form. However, one intriguing aspect of Windows Forms development is the fact that Form types can function as the base class to derived Forms. For example, assume you create a .NET code library that contains each of your company’s core dialog boxes. Later, you decide that your company’s About box is a bit on the bland side, and you wish to add a 3D image of your company logo. Rather than having to re-create the entire About box, you can extend the basic About box, thereby inheriting the core look-and-feel:
// ThreeDAboutBox "is-a" AboutBox public partial class ThreeDAboutBox : AboutBox { // Add code to render company logo... }
To see form inheritance in action, insert a new form into your project using the Project ➤ Add Windows Form menu option. This time, however, pick the Inherited Form icon, and name your new form ImageOrderAutoDialog.cs (see Figure A-18).
1543
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Figure A-18. Adding a derived form to your project
This option brings up the Inheritance Picker dialog box, which shows you each of the forms in your current project. Notice that the Browse button allows you to pick a form in an external .NET assembly. Here, simply pick your OrderAutoDialog class.
■ Note You must compile your project at least one time to see the forms of your project in the Inheritance Picker dialog box because this tool reads from the assembly metadata to show you your options.
Once you click the OK button, the visual designer tools show each of the base controls on your parent controls; each control has a small arrow icon mounted on the upper-left of the control (symbolizing inheritance). To complete your derived dialog box, locate the PictureBox control from the Common Controls section of the Toolbox and add one to your derived form. Next, use the Image property to select an image file of your choosing. Figure A-19 shows one possible UI, using a (crude) hand drawing of a junker automobile (a lemon!).
1544
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Figure A-19. The UI of the ImageOrderAutoDialog class
With this, you can now update the Tools ➤ Order Automobile... Click event handler to create an instance of your derived type, rather than the OrderAutoDialog base class: private void orderAutomobileToolStripMenuItem_Click(object sender, EventArgs e) { // Create the derived dialog object. ImageOrderAutoDialog dlg = new ImageOrderAutoDialog(); ... }
■ Source Code You can find the CarOrderApp project under the Appendix A subdirectory.
Rendering Graphical Data Using GDI+ Many GUI applications require the ability to generate graphical data dynamically for display on the surface of a window. For example, perhaps you have selected a set of records from a relational database and wish to render a pie chart (or bar chart) that visually shows items in stock. Or, perhaps you want to re-create some old-school video game using the .NET platform. Regardless of your goal, GDI+ is the API to use when you need to render data graphically within a Windows Forms application. This technology is bundled within the System.Drawing.dll assembly, which defines a number of namespaces (see Figure A-20).
1545
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Figure A-20. The namespaces of System.Drawing.dll
■ Note A friendly reminder: WPF has its own graphical rendering subsystem and API; you use GDI+ only within a Windows Forms application.
Table A-10 documents the role of the key GDI+ namespaces at a high level.
Table A-10. Core GDI+ Namespaces
Namespace Meaning in Life
System.Drawing This is the core GDI+ namespace that defines numerous types for basic rendering (e.g., fonts, pens, and basic brushes), as well as the almighty Graphics type.
System.Drawing.Drawing2D This namespace provides types used for more advanced 2D/vector graphics functionality (e.g., gradient brushes, pen caps, and geometric transforms).
System.Drawing.Imaging This namespace defines types that allow you to manipulate graphical images (e.g., change the palette, extract image metadata, manipulate metafiles, etc.).
System.Drawing.Printing This namespace defines types that allow you to render images to the printed page, interact with the printer itself, and format the overall appearance of a given print job.
System.Drawing.Text This namespace allows you to manipulate collections of fonts.
1546
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
The System.Drawing Namespace You can find the vast majority of the types you’ll use when programming GDI+ applications in the System.Drawing namespace. As you might expect, you can find classes that represent images, brushes, pens, and fonts. System.Drawing also defines a several related utility types, such as Color, Point, and Rectangle. Table A-11 lists some (but not all) of the core types.
Table A-11. Core Types of the System.Drawing Namespace
Type Meaning in Life
Bitmap This type encapsulates image data (*.bmp or otherwise).
Brush You use brush objects to fill the interiors of graphical shapes, such as rectangles, Brushes ellipses, and polygons. SolidBrush SystemBrushes TextureBrush
BufferedGraphics This type provides a graphics buffer for double buffering, which you use to reduce or eliminate flicker caused by redrawing a display surface.
Color The Color and SystemColors types define a number of static read-only properties SystemColors you use to obtain specific colors for the construction of various pens/brushes.
Font The Font type encapsulates the characteristics of a given font (e.g., type name, FontFamily bold, italic, and point size). FontFamily provides an abstraction for a group of fonts that have a similar design, but also certain variations in style.
Graphics This core class represents a valid drawing surface, as well as several methods to render text, images, and geometric patterns.
Icon These classes represent custom icons, as well as the set of standard system- SystemIcons supplied icons.
Image Image is an abstract base class that provides functionality for the Bitmap, Icon, ImageAnimator and Cursor types. ImageAnimator provides a way to iterate over a number of Image-derived types at some specified interval.
Pen Pens are objects you use to draw lines and curves. The Pens type defines several Pens static properties that return a new Pen of a given color. SystemPens
Point These structures represent an (x, y) coordinate mapping to an underlying integer PointF or float, respectively.
1547
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Table A-11. Core Types of the System.Drawing Namespace (continued)
Type Meaning in Life
Rectangle These structures represent a rectangular dimension (again, these map to an RectangleF underlying integer or float).
Size These structures represent a given height/width (again, these map to an underlying SizeF integer or float).
StringFormat You use this type to encapsulate various features of textual layout (e.g., alignment and line spacing).
Region This type describes the interior of a geometric image composed of rectangles and paths.
The Role of the Graphics Type The System.Drawing.Graphics class serves as the gateway to GDI+ rendering functionality. This class not only represents the surface you wish to draw upon (such as a form’s surface, a control’s surface, or a region of memory), but also defines dozens of members that allow you to render text, images (e.g., icons and bitmaps), and numerous geometric patterns. Table A-12 gives a partial list of members.
Table A-12. Select Members of the Graphics Class
Method Meaning in Life
FromHdc() These static methods provide a way to obtain a valid Graphics object from a FromHwnd() given image (e.g., icon and bitmap) or GUI control. FromImage()
Clear() This method fills a Graphics object with a specified color, erasing the current drawing surface in the process.
DrawArc() You use these methods to render a given image or geometric pattern. DrawBeziers() All DrawXXX() methods require that you use GDI+ Pen objects. DrawCurve() DrawEllipse() DrawIcon() DrawLine() DrawLines() DrawPie() DrawPath() DrawRectangle() DrawRectangles() DrawString()
1548
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Table A-12. Select Members of the Graphics Class (continued)
Method Meaning in Life
FillEllipse() You use these methods to fill the interior of a given geometric shape. FillPie() All FillXXX() methods require that you use GDI+ Brush objects. FillPolygon() FillRectangle() FillPath()
Note that you cannot create the Graphics class directly using the new keyword because there are no publicly defined constructors. So, how do you obtain a valid Graphics object? I’m glad you asked!
Obtaining a Graphics Object with the Paint Event The most common way to obtain a Graphics object is to use the Visual Studio 2010 Properties window to handle the Paint event on the window you want to render upon. This event is defined in terms of the PaintEventHandler delegate, which can point to any method taking a System.Object as the first parameter and a PaintEventArgs as the second. The PaintEventArgs parameter contains the Graphics object you need to render onto the Form’s surface. For example, create a new Windows Application project named PaintEventApp. Next, use Solution Explorer to rename your initial Form.cs file to MainWindow.cs, and then handle the Paint event using the Properties window. This creates the following stub code: public partial class MainWindow : Form { public MainWindow() { InitializeComponent(); }
private void MainWindow_Paint(object sender, PaintEventArgs e) { // Add your painting code here! } } Now that you have handled the Paint event, you might wonder when it will fire. The Paint event fires whenever a window becomes dirty; a window is considered dirty whenever it is resized, uncovered by another window (partially or completely), or minimized and then restored. In all these cases, the .NET platform ensures that the Paint event handler is called automatically whenever your Form needs to be redrawn. Consider the following implementation of MainWindow_Paint(): private void MainWindow_Paint(object sender, PaintEventArgs e) { // Get the graphics object for this Form. Graphics g = e.Graphics;
// Draw a circle. g.FillEllipse(Brushes.Blue, 10, 20, 150, 80);
1549
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
// Draw a string in a custom font. g.DrawString("Hello GDI+", new Font("Times New Roman", 30), Brushes.Red, 200, 200);
// Draw a line with a custom pen. using (Pen p = new Pen(Color.YellowGreen, 10)) { g.DrawLine(p, 80, 4, 200, 200); } } Once you obtain the Graphics object from the incoming PaintEventArgs parameter, you call FillEllipse(). Notice that this method (as well as any Fill-prefixed method) requires a Brush-derived type as the first parameter. While you could create any number of interesting brush objects from the System.Drawing.Drawing2D namespace (e.g., HatchBrush and LinearGradientBrush), the Brushes utility class provides handy access to a variety of solid-colored brush types. Next, you make a call to DrawString(), which requires a string to render as its first parameter. Given this, GDI+ provides the Font type, which represents not only the name of the font to use when rendering the textual data, but also related characteristics, such as the point size (30, in this case). Also notice that DrawString() requires a Brush type; as far as GDI+ is concerned, “Hello GDI+” is nothing more than a collection of geometric patterns to fill on the screen. Finally, DrawLine() is called to render a line using a custom Pen type, 10 pixels wide. Figure A-21 shows the output of this rendering logic.
Figure A-21. A simple GDI+ rendering operation
■ Note In the preceding code, you explicitly dispose of the Pen object. As a rule, when you directly create a GDI+ type that implements IDisposable, you call the Dispose() method as soon as you are done with the object. Doing this lets you release the underlying resources as soon as possible. If you do not do this, the resources will eventually be freed by the garbage collector in a nondeterministic manner.
1550
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Invalidating the Form’s Client Area During the flow of a Windows Forms application, you might need to fire the Paint event in your code explicitly, rather than waiting for the window to become naturally dirty by the actions of the end user. For example, you might be building a program that allows the user to select from a number of predefined images using a custom dialog box. Once the dialog box is dismissed, you need to draw the newly selected image onto the form’s client area. Obviously, if you were to wait for the window to become naturally dirty, the user would not see the change take place until the window was resized or uncovered by another window. To force a window to repaint itself programmatically, you call the inherited Invalidate() method: public partial class MainForm: Form { ... private void MainForm_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; // Render the correct image here. }
private void GetImageFromDialog() { // Show dialog box and get new image. // Repaint the entire client area. Invalidate(); } }
The Invalidate() method has been overloaded a number of times. This allows you to specify a specific rectangular portion of the form to repaint, rather than having to repaint the entire client area (which is the default). If you wish to update only the extreme upper-left rectangle of the client area, you can write the following code:
// Repaint a given rectangular area of the Form. private void UpdateUpperArea() { Rectangle myRect = new Rectangle(0, 0, 75, 150); Invalidate(myRect); }
■ Source Code You can find the PaintEventApp project under the Appendix A subdirectory.
Building a Complete Windows Forms Application Let’s conclude this introductory look at the Windows Forms and GDI+ APIs by building a complete GUI application that illustrates several of the techniques discussed in this chapter. The program you will create is a rudimentary painting program that allows users to select between two shape types (a circle or
1551
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
rectangle) using the color of their choice to render data to the form. You will also allow end users to save their pictures to a local file on their hard drive for later use with object serialization services.
Building the Main Menu System Begin by creating a new Windows Forms application named MyPaintProgram and rename your initial Form1.cs file to MainWindow.cs. Now design a menu system on this initial window that supports a topmost File menu that provides Save..., Load..., and Exit submenus (see Figure A-22).
Figure A-22. The File menu system
■ Note If you specify a single dash (-) as a menu item, you can define separators within your menu system.
Next, create a second topmost Tools menu that provides options to select a shape and color to use for rendering, as well as an option to clear the form of all graphical data (see Figure A-23).
Figure A-23. The Tools Menu System
1552
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Finally, handle the Click event for each one of these subitems. You will implement each handler as you progress through the example; however, you can finish up the File ➤ Exit menu handler by calling Close(): private void exitToolStripMenuItem_Click(object sender, EventArgs e) { Close(); }
Defining the ShapeData Type Recall that this application will allow end users to select from two predefined shapes in a given color. You will provide a way to allow users to save their graphical data to a file, so you want to define a custom class type that encapsulates each of these details; for the sake of simplicity, you do this using C# automatic properties (see Chapter 5 for more details on how to do this). Begin by adding a new class to your project named ShapeData.cs and implementing this type as follows:
[Serializable] class ShapeData { // The upper left of the shape to be drawn. public Point UpperLeftPoint { get; set; }
// The current color of the shape to be drawn. public Color Color { get; set; }
// The type of shape. public SelectedShape ShapeType { get; set; } }
Here, ShapeData uses three automatic properties that encapsulates various types of data, two of which (Point and Color) are defined in the System.Drawing namespace, so be sure to import this namespace into your code file. Also, notice that this type has been adorned with the [Serializable] attribute. In an upcoming step, you will configure your MainWindow type to maintain a list of ShapeData types that you persist using object serialization services (see Chapter 20 for more details).
Defining the ShapePickerDialog Type You can allow the user to choose between the circle or rectangle image type by creating a simple custom dialog box named ShapePickerDialog (insert this new Form now). Beyond adding the obligatory OK and Cancel buttons (each of which you should assign fitting DialogResult values), this dialog box uses of a single GroupBox that maintains two RadioButton objects: radioButtonCircle and radioButtonRect. Figure A-24 shows one possible design.
1553
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Figure A-24. The ShapePickerDialog type
Now, open the code window for your dialog box by right-clicking the Forms designer and selecting the View Code menu option. Within the MyPaintProgram namespace, define an enumeration (named SelectedShape) that defines names for each possible shape:
public enum SelectedShape { Circle, Rectangle } Next, update your current ShapePickerDialog class type: • Add an automatic property of type SelectedShape. The caller can use this property to determine which shape to render. • Handle the Click event for the OK button using the Properties window. • Implement this event handler to determine whether the circle radio button has been selected (through the Checked property). If so, set your SelectedShape property to SelectedShape.Circle; otherwise, set this property to SelectedShape.Rectangle. Here is the complete code:
public partial class ShapePickerDialog : Form { public SelectedShape SelectedShape { get; set; }
public ShapePickerDialog() { InitializeComponent(); }
private void btnOK_Click(object sender, EventArgs e) { if (radioButtonCircle.Checked) SelectedShape = SelectedShape.Circle; else
1554
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
SelectedShape = SelectedShape.Rectangle; } }
That wraps up the infrastructure of your program. Now all you need to do is implement the Click event handlers for the remaining menu items on the main window.
Adding Infrastructure to the MainWindow Type Returning to the construction of the main window, add three new member variables to this Form. These member variables allow you to keep track of the selected shape (through a SelectedShape enum member variable), the selected color (represented by a System.Drawing.Color member variable), and through each of the rendered images held in a generic List
// This maintains each ShapeData. private List
Next, you handle the MouseDown and Paint events for this Form-derived type using the Properties window. You will implement them in a later step; for the time being, however, you should find that the IDE has generated the following stub code: private void MainWindow_Paint(object sender, PaintEventArgs e) { } private void MainWindow_MouseDown(object sender, MouseEventArgs e) { }
Implementing the Tools Menu Functionality You can allow a user to set the currentShape member variable by implementing the Click handler for the Tools ➤ Pick Shape... menu option. You use this to launch your custom dialog box; based on a user’s selection, you assign this member variable accordingly: private void pickShapeToolStripMenuItem_Click(object sender, EventArgs e) { // Load our dialog box and set the correct shape type. ShapePickerDialog dlg = new ShapePickerDialog(); if (DialogResult.OK == dlg.ShowDialog()) {
1555
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
currentShape = dlg.SelectedShape; } }
You can let a user set the currentColor member variable by implementing the Click event handler for the Tools ➤ Pick Color... menu so it uses the System.Windows.Forms.ColorDialog type:
private void pickColorToolStripMenuItem_Click(object sender, EventArgs e) { ColorDialog dlg = new ColorDialog();
if (dlg.ShowDialog() == DialogResult.OK) { currentColor = dlg.Color; } }
If you were to run your program as it now stands and select the Tools ➤ Pick Color menu option, you would get the dialog box shown in Figure A-25.
Figure A-25. The stock ColorDialog type
Finally, you implement the Tools ➤ Clear Surface menu handler so it empties the contents of the List
private void clearSurfaceToolStripMenuItem_Click(object sender, EventArgs e) { shapes.Clear();
// This will fire the paint event. Invalidate(); }
1556
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Capturing and Rendering the Graphical Output Given that a call to Invalidate() fires the Paint event, you need to author code within the Paint event handler. Your goal is to loop through each item in the (currently empty) List
// Add to the List
At this point, you can implement your Paint event handler: private void MainWindow_Paint(object sender, PaintEventArgs e) { // Get the Graphics object for this window. Graphics g = e.Graphics;
// Render each shape in the selected color. foreach (ShapeData s in shapes) { // Render a rectangle or circle 20 x 20 pixels in size // using the correct color. if (s.ShapeType == SelectedShape.Rectangle) g.FillRectangle(new SolidBrush(s.Color), s.UpperLeftPoint.X, s.UpperLeftPoint.Y, 20, 20); else g.FillEllipse(new SolidBrush(s.Color), s.UpperLeftPoint.X, s.UpperLeftPoint.Y, 20, 20); } }
If you run your application at this point, you should be able to render any number of shapes in a variety of colors (see Figure A-26).
1557
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Figure A-26. MyPaintProgram in action
Implementing the Serialization Logic The final aspect of this project involves implementing Click event handlers for the File ➤ Save... and File ➤ Load... menu items. Given that ShapeData has been marked with the [Serializable] attribute (and given that List
// For the binary formatter. using System.Runtime.Serialization.Formatters.Binary; using System.IO;
Now update your File ➤ Save... handler, as follows:
private void saveToolStripMenuItem_Click(object sender, EventArgs e) { using (SaveFileDialog saveDlg = new SaveFileDialog()) { // Configure the look and feel of the save dialog box. saveDlg.InitialDirectory = "."; saveDlg.Filter = "Shape files (*.shapes)|*.shapes"; saveDlg.RestoreDirectory = true; saveDlg.FileName = "MyShapes";
// If they click the OK button, open the new // file and serialize the List
1558
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
BinaryFormatter myBinaryFormat = new BinaryFormatter(); myBinaryFormat.Serialize(myStream, shapes); myStream.Close(); } } } }
The File ➤ Load event handler opens the selected file and deserializes the data back into the List
if (openDlg.ShowDialog() == DialogResult.OK) { Stream myStream = openDlg.OpenFile(); if ((myStream != null)) { // Get the shapes! BinaryFormatter myBinaryFormat = new BinaryFormatter(); shapes = (List
After Chapter 20, the overall serialization logic here should look familiar. It is worth pointing out that the SaveFileDialog and OpenFileDialog types both support a Filter property that is assigned a rather cryptic string value. This filter controls a number of settings for the save/open dialog boxes, such as the file extension (*.shapes). You use the FileName property to control what the default name of the file you want to create—MyShapes, in this example. At this point, your painting application is complete. You should now be able to save and load your current graphical data to any number of *.shapes files. If you want to enhance this Windows Forms program, you might wish to account for additional shapes, or even to allow the user to control the size of the shape to draw or perhaps select the format used to save the data (e.g., binary, XML, or SOAP; see Chapter 20).
1559
APPENDIX A ■ PROGRAMMING WITH WINDOWS FORMS
Summary This chapter examined the process of building traditional desktop applications using the Windows Forms and GDI+ APIs, which have been part of the .NET Framework since version 1.0. At minimum, a Windows Forms application consists of a type-extending Form and a Main() method that interacts with the Application type. When you want to populate your forms with UI elements (e.g., menu systems and GUI input controls), you do so by inserting new objects into the inherited Controls collection. This chapter also showed you how to capture mouse, keyboard, and rendering events. Along the way, you learned about the Graphics type and many ways to generate graphical data at runtime. As mentioned in this chapter’s overview, the Windows Forms API has been (in some ways) superseded by the WPF API introduced with the release of .NET 3.0 (which you learned about in some detail in Part 6 of this book). While it is true that WPF is the choice for supercharged UI front ends, the Windows Forms API remains the simplest (and in many cases, most direct) way to author standard business applications, in-house applications, and simple configuration utilities. For these reasons, Windows Forms will be part of the .NET base class libraries for years to come.
1560
A P P E N D I X B
■ ■ ■
Platform-Independent .NET Development with Mono
This appendix introduces you to the topic of cross-platform C# and .NET development using an open source implementation of .NET named Mono (in case you are wondering about the name, mono is a Spanish word for monkey, which is a reference to the various monkey-mascots used by the initial creators of the Mono platform, Ximian Corporation). In this appendix, you will learn about the role of the Common Language Infrastructure (CLI), the overall scope of Mono, and various Mono development tools. At the conclusion of this appendix-and given your work over the course of this book—you will be in a perfect position to dig further into Mono development as you see fit.
■ Note If you require a detailed explanation of cross-platform .NET development, I recommend picking up a copy of Cross-Platform .NET Development: Using Mono, Portable .NET, and Microsoft .NET by Mark Easton and Jason King (Apress, 2004).
The Platform-Independent Nature of .NET Historically speaking, when programmers used a Microsoft development language (e.g., VB6) or Microsoft programming framework (e.g., MFC, COM, or ATL), they had to resign themselves to building software that (by-and-large) executed only on the Windows family of operating systems. Many .NET developers, accustomed to previous Microsoft development options, are frequently surprised when they learn that .NET is platform-independent. But it’s true. You can create, compile, and execute .NET assemblies on operating systems other than Microsoft Windows. Using open source .NET implementations such as Mono, your .NET applications can find happy homes on numerous operating systems, including Mac OS X, Solaris, AIX, and numerous flavors of Unix/Linux. Mono also provides an installation package for (surprise, surprise) Microsoft Windows. Thus, it is possible to build and run .NET assemblies on the Windows operating system, without ever installing the Microsoft .NET Framework 4.0 SDK or the Visual Studio 2010 IDE.
1561
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
■ Note Be aware that the Microsoft .NET Framework 4.0 SDK and Visual Studio 2010 are your best options for building .NET software for the Windows family of operating systems.
Even after developers learn about .NET code’s cross-platform capabilities, they often assume that the scope of platform-independent .NET development is limited to little more than Hello World console applications. The reality is that you can build production-ready assemblies that use ADO.NET, Windows Forms (in addition to alternative GUI toolkits such as GTK# and Cocoa#), ASP.NET, LINQ, and XML web services by taking advantage of many of the core namespaces and language features you have seen featured throughout this book.
The Role of the CLI .NET’s cross-platform capabilities are implemented differently than the approach taken by Sun Microsystems and its handling of the Java programming platform. Unlike Java, Microsoft itself does not provide .NET installers for Mac, Linux, and so on. Rather, Microsoft has released a set of formalized specifications that other entities can use as a road map for building .NET distributions for their platform(s) of choice. Collectively, these specifications are termed the Common Language Infrastructure (CLI). As briefly mentioned in Chapter 1, Microsoft submitted two formal specifications to ECMA (European Computer Manufacturers Association) when it released C# and the .NET platform to the world at large. Once approved, Microsoft submitted these same specifications to the International Organization for Standardization (ISO), and these specifications were ratified shortly thereafter. So, why should you care? These two specifications provide a road map for other companies, developers, universities, and other organizations to build their own custom distributions of the C# programming language and the .NET platform. The two specifications in question are: • ECMA-334: Defines the syntax and semantics of the C# programming language. • ECMA-335: Defines many details of the .NET platform, collectively called the Common Language Infrastructure. ECMA-334 tackles the lexical grammar of C# in an extremely rigorous and scientific manner (as you might guess, this level of detail is quite important to those who want to implement a C# compiler). However, ECMA-335 is the meatier of the two specifications, so much so that it has been broken down into six partitions (see Table B-1).
1562
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
Table B-1. ECMA-335 Specification Partitions
ECMA-335 Partition Meaning in Life
Partition I: Concepts and Describes the overall architecture of the CLI, including the Architecture rules of the Common Type System, the Common Language Specification, and the mechanics of the .NET runtime engine.
Partition II: Metadata Describes the details of the .NET metadata format. Definition and Semantics
Partition III: CIL Describes the syntax and semantics of the common Instruction Set intermediate language (CIL) programming language.
Partition IV: Profiles and Provides a high-level overview of the minimal and complete Libraries class libraries that must be supported by a CLI-compatible .NET distribution.
Partition V: Debug Provides details of the portable debug interchange format Interchange Formats (CILDB). Portable CILDB files provide a standard way to exchange debugging information between CLI producers and consumers.
Partition VI: Annexes Represents a collection of odds and ends; it clarifies topics such as class library design guidelines and the implementation details of a CIL compiler.
The point of this appendix is not to dive into the details of the ECMA-334 and ECMA-335 specifications—nor must you know the ins-and-outs of these documents to understand how to build platform-independent .NET assemblies. However, if you are interested, you can download both of these specifications for free from the ECMA website (http://www.ecma- international.org/publications/standards).
The Mainstream CLI Distributions To date, you can find two mainstream implementations of the CLI beyond Microsoft’s CLR, Microsoft Silverlight, and the Microsoft NET Compact Framework (see Table B-2).
1563
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
Table B-2. Mainstream .NET CLI Distributions
CLI Distribution Supporting Website Meaning in Life
Mono www.mono-project.com Mono is an open source and commercially supported distribution of .NET sponsored by Novell Corporation. Mono is targeted to run on many popular flavors of Unix/Linux, Mac OS X, Solaris, and Windows.
Portable .NET www.dotgnu.org Portable .NET is distributed under the GNU General Public License. As the name implies, Portable .NET intends to function on as many operation systems and architectures as possible, including esoteric platforms such as BeOS, Microsoft Xbox, and Sony PlayStation (no, I’m not kidding about the last two!).
Each of the CLI implementations shown in Table B-2 provide a fully function C# compiler, numerous command-line development tools, a global assembly cache (GAC) implementation, sample code, useful documentation, and dozens of assemblies that constitute the base class libraries. Beyond implementing the core libraries defined by Partition IV of ECMA-335, Mono and Portable .NET provide Microsoft-compatible implementations of mscorlib.dll, System.Core.dll, System.Data.dll, System.Web.dll, System.Drawing.dll, and System.Windows.Forms.dll (among many others). The Mono and Portable .NET distributions also ship with a handful of assemblies specifically targeted at Unix/Linux and Mac OS X operating systems. For example, Cocoa# is a .NET wrapper around the preferred Mac OX GUI toolkit, Cocoa. In this appendix, I will not dig into these OS-specific binaries; instead, I’ll focus on using the OS-agonistic programming stacks.
■ Note This appendix will not examine Portable .NET; however, it is important to know that Mono is not the only platform-independent distribution of the .NET platform available today. I recommend you take some time to play around with Portable .NET in addition to the Mono platform.
The Scope of Mono Given that Mono is an API built on existing ECMA specifications that originated from Microsoft, you would be correct in assuming that Mono is playing a constant game of catch up as newer versions of Microsoft’s .NET platform are released. At the time of this writing, Mono is compatible with C# 2008 (work on the new C# 2010 language features are in development as I type) and .NET 2.0. This means you can build ASP.NET websites, Windows Forms applications, database-centric applications using ADO.NET, and (of course) simple console applications.
1564
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
Currently, Mono is not completely compatible with the new features of C# 2010 (e.g., optional arguments and the dynamic keyword) or with all aspects of .NET 3.0-4.0. This means that Mono applications are currently unable (again, at the time of this writing) to use the following Microsoft .NET APIs: • Windows Presentation Foundation (WPF) • Windows Communication Foundation (WCF) • Windows Workflow Foundation (WF) • LINQ to Entities (however, LINQ to Objects and LINQ to XML are supported) • Any C# 2010 specific language features Some of these APIs might eventually become part of the standard Mono distribution stacks. For example, according to the Mono website, future versions of the platform (2.8-3.0) will provide support for C# 2010 language features and .NET 3.5-4.0 platform features. In addition to keeping-step with Microsoft’s core .NET APIs and C# language features, Mono also provides an open source distribution of the Silverlight API named Moonlight. This enables browsers that run under Linux based operating systems to host and use Silverlight / Moonlight web applications. As you might already know, Microsoft’s Silverlight already includes support for Mac OS X; and given the Moonlight API, this technology has truly become cross-platform. Mono also supports some .NET based technologies that do not have a direct Microsoft equivalent. For example, Mono ships with GTK#, a .NET wrapper around a popular Linux-centric GUI framework named GTK. One compelling Mono-centric API is MonoTouch, which allows you to build applications for Apple iPhone and iTouch devices using the C# programming language.
■ Note The Mono website includes a page that describes the overall road map of Mono’s functionality and the project’s plans for future releases (www.mono-project.com/plans).
A final point of interest regarding the Mono feature set: Much like Microsoft’s .NET Framework 4.0 SDK, the Mono SDK supports several .NET programming languages. While this appendix focuses on C#, Mono also provides support for a Visual Basic compiler, as well as support for many other .NET-aware programming languages.
Obtaining and Installing Mono Now that you have a better idea what you can do with the Mono platform, let’s turn our attention to obtaining and installing Mono itself. Navigate to the Mono website (www.mono-project.com) and locate the Download tab to navigate to the downloads page. Here you can download a variety of installers (see Figure B-1).
1565
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
Figure B-1. The Mono Download Page
This appendix assumes that you are installing the Windows distribution of Mono (note that installing Mono will not interfere whatsoever with any existing installation of Microsoft .NET or Visual Studio IDEs). Begin by downloading the current, stable Mono installation package for Microsoft Windows and saving the setup program to your local hard drive. When you run the setup program, you are given a chance to install a variety of Mono development tools beyond the expected base class libraries and the C# programming tools. Specifically, the installer will ask you whether you wish to include GTK# (the open source .NET GUI API based on the Linux- centric GTK toolkit) and XSP (a stand-alone web server, similar to Microsoft’s ASP.NET development web server [webdev.webserver.exe]). This appendix also assumes you have opted for a Full Installation, which selects each option in the setup script (see Figure B-2).
1566
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
Figure B-2. Select All Options for Your Mono Installation
Examining Mono’s Directory Structure By default, Mono installs under C:\Program Files\Mono-
1567
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
Figure B-3. The Mono Directory Structure
For this appendix, you need to concern yourself only with the following subdirectories: • bin: Contains a majority of the Mono development tools, including the C# command-line compilers. • lib\mono\gac: Points to the location of Mono’s global assembly cache. Given that you run the vast majority of Mono’s development tools from the command line, you will want to use the Mono command prompt, which automatically recognizes each of the command-line development tools. You can activate the command prompt (which is functionally equivalent to the Visual Studio 2010 command prompt) by selecting Start ➤ All Programs ➤ Mono
mono --version
If all is well, you should see various details regarding the Mono runtime environment. Here is the output on my Mono development machine:
1568
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
Mono JIT compiler version 2.4.2.3 (tarball) Copyright (C) 2002-2008 Novell, Inc and Contributors. www.mono-project.com TLS: normal GC: Included Boehm (with typed GC) SIGSEGV: normal Notification: Thread + polling Architecture: x86 Disabled: none
The Mono Development Languages Similar to the Microsoft’s CLR distribution, Mono ships with a number of managed compilers: • mcs: The Mono C# compiler • vbnc: The Mono Visual Basic .NET compiler • booc: The Mono Boo language compiler • ilasm: The Mono CIL compilers While this appendix focuses only on the C# compilers, you should keep in mind that the Mono project does ship with a Visual Basic compiler. While this tool is currently under development, the intended goal is to bring the world of human-readable keywords (e.g., Inherits, MustOverride, and Implements) to the world of Unix/Linux and Mac OS X (see www.mono-project.com/Visual_Basic for more details). Boo is an object-oriented, statically typed programming language for the CLI that sports a Python- based syntax. Check out http://boo.codehaus.org for more details on the Boo programming language. Finally, as you might have guessed, ilasm is the Mono CIL compiler.
Working with the C# Compiler The C# compiler for the Mono project was mcs, and it’s fully compatible with C# 2008. Like the Microsoft C# command-line compiler (csc.exe), mcs supports response files, a /target: flag (to define the assembly type), an /out: flag (to define the name of the compiled assembly), and a /reference: flag (to update the manifest of the current assembly with external dependencies). You can view all the options of mcs using the following command: mcs -?
Building Mono Applications using MonoDevelop When you install Mono, you will not be provided with a graphical IDE. However, this does not mean you must build all of your Mono applications at the command prompt! In addition to the core framework, you can also download the free MonoDevelop IDE. As its name suggests, MonoDevelop was built using the core code base of SharpDevelop (see Chapter 2).
1569
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
You can download the MonoDevelop IDE from the Mono website, and it supports installation packages for Mac OS X, various Linux distributions, and (surprise!) Microsoft Windows! Once installed, you might be pleased to find an integrated debugger, IntelliSense capabilities, numerous project templates (e.g., ASP.NET and Moonlight). You can get a taste of what the MonoDevelop IDE brings to the table by perusing Figure B-4.
Figure B-4. The MonoDevelop IDE Microsoft-Compatible Mono Development Tools In addition to the managed compilers, Mono ships with various development tools that are functionally equivalent to tools found in the Microsoft .NET SDK (some of which are identically named). Table B-3 enumerates the mappings between some of the commonly used Mono/Microsoft .NET utilities.
Table B-3. Mono Command-Line Tools and Their Microsoft .NET Counterparts
Mono Utility Microsoft .NET Utility Meaning in Life
al al.exe Manipulates assembly manifests and builds multifile assemblies (among other things).
gacutil gacutil.exe Interacts with the GAC.
mono when run with the -aot ngen.exe Performs a precompilation of an assembly’s option as a startup parameter CIL code. to the executing assembly
1570
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
Table B-3. Mono Command-Line Tools and Their Microsoft .NET Counterparts (continued)
Mono Utility Microsoft .NET Utility Meaning in Life
wsdl wsdl.exe Generates client-side proxy code for XML web services.
disco disco.exe Discovers the URLs of XML web services located on a web server.
xsd xsd.exe Generates type definitions from an XSD schema file.
sn sn.exe Generates key data for a strongly named assembly.
monodis ildasm.exe The CIL disassembler
ilasm ilasm.exe The CIL assembler
xsp2 webdev.webserver.exe A testing and development ASP.NET web server
Mono-Specific Development Tools Mono also ships with development tools for which no direct Microsoft .NET Framework 3.5 SDK equivalents exist (see Table B-4).
Table B-4. Mono Tools That Have No Direct Microsoft .NET SDK Equivalent
Mono-Specific Development Tool Meaning in Life
monop The monop (mono print) utility displays the definition of a specified type using C# syntax (see the next section for a quick example). SQL# The Mono Project ships with a graphical front end (SQL#) that allows you to interact with relational databases using a variety of ADO.NET data providers. Glade 3 This tool is a visual development IDE for building GTK# graphical applications.
1571
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
■ Note You can load SQL# and Glade by using the Windows Start button and navigating to the Applications folder within the Mono installation. Be sure to do this because this illustrates definitively how rich the Mono platform has become.
Using monop You can use the monop utility (short for mono print) to display the C# definition of a given type within a specified assembly. As you might suspect, this tool can be quite helpful when you wish to view a method signature quickly, rather than digging through the formal documentation. As a quick test, try entering the following command at a Mono command prompt:
monop System.Object
You should see the definition of your good friend, System.Object:
[Serializable] public class Object {
public Object ();
public static bool Equals (object objA, object objB); public static bool ReferenceEquals (object objA, object objB); public virtual bool Equals (object obj); protected override void Finalize (); public virtual int GetHashCode (); public Type GetType (); protected object MemberwiseClone (); public virtual string ToString (); }
Building .NET Applications with Mono Now let’s look at Mono in action. You begin by building a code library named CoreLibDumper.dll. This assembly contains a single class type named CoreLibDumper that supports a static method named DumpTypeToFile(). The method takes a string parameter that represents the fully qualified name of any type within mscorlib.dll and obtains the related type information through the reflection API (see Chapter 15), dumping the class member signatures to a local file on the hard drive.
Building a Mono Code Library Create a new folder on your C: drive named MonoCode. Within this new folder, create a subfolder named CorLibDumper that contains the following C# file (named CorLibDumper.cs):
1572
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
// CorLibDumper.cs using System; using System.Reflection; using System.IO;
// Define assembly version. [assembly:AssemblyVersion("1.0.0.0")] namespace CorLibDumper { public class TypeDumper { public static bool DumpTypeToFile(string typeToDisplay) { // Attempt to load type into memory. Type theType = null; try { // Second parameter to GetType() controls if an // exception should be thrown if the type is not found. theType = Type.GetType(typeToDisplay, true); } catch { return false; }
// Create local *.txt file. using(StreamWriter sw = File.CreateText(string.Format("{0}.txt", theType.FullName))) { // Now dump type to file. sw.WriteLine("Type Name: {0}", theType.FullName); sw.WriteLine("Members:"); foreach(MemberInfo mi in theType.GetMembers()) sw.WriteLine("\t-> {0}", mi.ToString());
} return true; } } }
Like the Microsoft C# compiler, Mono’s C# compilers support the use of response files (see Chapter 2). While you could compile this file by specifying each required argument manually at the command line, you can instead create a new file named LibraryBuild.rsp (in the same location as CorLibDumper.cs) that contains the following command set:
/target:library /out:CorLibDumper.dll CorLibDumper.cs
You can now compile your library at the command line, as follows: mcs @LibraryBuild.rsp
1573
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
This approach is functionally equivalent to the following (more verbose) command set:
mcs /target:library /out:CorLibDumper.dll CorLibDumper.cs
Assigning CoreLibDumper.dll a Strong Name Mono supports the notion of deploying strongly named assemblies (see Chapter 15) to the Mono GAC. To generate the necessary public/private key data, Mono provides the sn command-line utility, which functions more or less identically to Microsoft’s tool of the same name. For example, the following command generates a new *.snk file (specify the -? option to view all possible commands):
sn -k myTestKeyPair.snk
You can tell the C# compiler to use this key data to assign a strong name to CorLibDumper.dll by updating your LibraryBuild.rsp file with the following additional command:
/target:library /out:CorLibDumper.dll /keyfile:myTestKeyPair.snk CorLibDumper.cs
Now recompile your assembly:
mcs @LibraryBuild.rsp
Viewing the Updated Manifest with monodis Before you deploy the assembly to the Mono GAC, you should familiarize yourself with the monodis command-line tool, which is the functional equivalent of Microsoft’s ildasm.exe (without the GUI front end). Using monodis, you can view the CIL code, manifest, and type metadata for a specified assembly. In this case, you want to view the core details of your (now strongly named) assembly using the --assembly flag. Figure B-5 shows the result of the following command set:
monodis --assembly CorLibDumper.dll
1574
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
Figure B-5. Viewing the CIL Code, Metadata, and Manifest of an Assembly with monodis
The assembly’s manifest now exposes the public key value defined in myTestKeyPair.snk.
Installing Assemblies into the Mono GAC So far you have provided CorLibDumper.dll with a strong name; you can install it into the Mono GAC using gacutil. Like Microsoft’s tool of the same name, Mono’s gacutil supports options to install, uninstall, and list the current assemblies installed under C:\Program Files\Mono-
■ Note Be sure to use a Mono command prompt to install this binary to the Mono GAC! If you use the Microsoft gacutil.exe program, you’ll install CorLibDumper.dll into the Microsoft GAC!
After you run the command, opening the \gac directory should reveal a new folder named CorLibDumper (see Figure B-6). This folder defines a subdirectory that follows the same naming conventions as Microsoft’s GAC (versionOfAssembly__publicKeyToken).
1575
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
Figure B-6. Deploying Your Code Library to the Mono GAC
■ Note Supplying the -l option to gacutil lists out each assembly in the Mono GAC.
Building a Console Application in Mono Your first Mono client will be a simple, console-based application named ConsoleClientApp.exe. Create a new file in your C:\MonoCode\CorLibDumper folder, ConsoleClientApp.cs, that contains the following Program class definition:
// This client app makes use of the CorLibDumper.dll // to dump type information to a file. using System; using CorLibDumper;
namespace ConsoleClientApp { public class Program { public static void Main(string[] args) { Console.WriteLine("***** The Type Dumper App *****\n");
// Ask user for name of type. string typeName = ""; Console.Write("Please enter type name: "); typeName = Console.ReadLine();
// Now send it to the helper library. if(TypeDumper.DumpTypeToFile(typeName))
1576
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
Console.WriteLine("Data saved into {0}.txt", typeName); else Console.WriteLine("Error! Can't find that type..."); } } }
Notice that the Main() method prompts the user for a fully qualified type name. The TypeDumper.DumpTypeToFile() method uses the user-entered name to dump the type’s members to a local file. Next, create a ClientBuild.rsp file for this client application and reference CorLibDumper.dll:
/target:exe /out:ConsoleClientApp.exe /reference:CorLibDumper.dll ConsoleClientApp.cs
Now, use a Mono command prompt to compile the executable using mcs, as shown here: mcs @ClientBuild.rsp
Loading Your Client Application in the Mono Runtime At this point, you can load ConsoleClientApp.exe into the Mono runtime engine by specifying the name of the executable (with the *.exe file extension) as an argument to Mono: mono ConsoleClientApp.exe
As a test, enter System.Threading.Thread at the prompt and press the Enter key. You will now find a new file named System.Threading.Thread.txt containing the type’s metadata definition (see Figure B-7).
Figure B-7. The Results of Running Your Client Application
1577
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
Before moving on to a Windows Forms–based client, try the following experiment. Use Windows Explorer to rename the CorLibDumper.dll assembly from the folder containing the client application to DontUseCorLibDumper.dll. You should still be able to run the client application successfully because the only reason you needed access to this assembly when building the client was to update the client manifest. At runtime, the Mono runtime will load the version of CorLibDumper.dll you deployed to the Mono GAC. However, if you open Windows Explorer and attempt to run your client application by double- clicking ConsoleClientApp.exe, you might be surprised to find a FileNotFoundException is thrown. At first glance, you might assume this is due to the fact that you renamed CorLibDumper.dll from the location of the client application. However, the true reason for the error is that you just loaded ConsoleClientApp.exe into the Microsoft CLR! To run an application under Mono, you must pass it into the Mono runtime through Mono. If you do not, you will be loading your assembly into the Microsoft CLR, which assumes all shared assemblies are installed into the Microsoft GAC located in the <%windir%>\Assembly directory.
■ Note If you double-click your executable using Windows Explorer, you will load your assembly into the Microsoft CLR, not the Mono runtime!
Building a Windows Forms Client Program Before continuing, be sure to rename DontUseCorLibDumper.dll back to CorLibDumper.dll, so you can compile the next example. Next, create a new C# file named WinFormsClientApp.cs and save it in the same location as your current project files. This file defines two class types:
using System; using System.Windows.Forms; using CorLibDumper; using System.Drawing;
namespace WinFormsClientApp { // Application object. public static class Program { public static void Main(string[] args) { Application.Run(new MainWindow()); } }
// Our simple Window. public class MainWindow : Form { private Button btnDumpToFile = new Button(); private TextBox txtTypeName = new TextBox();
1578
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
public MainWindow() { // Config the UI. ConfigControls(); }
private void ConfigControls() { // Configure the Form. Text = "My Mono Win Forms App!"; ClientSize = new System.Drawing.Size(366, 90); StartPosition = FormStartPosition.CenterScreen; AcceptButton = btnDumpToFile;
// Configure the Button. btnDumpToFile.Text = "Dump"; btnDumpToFile.Location = new System.Drawing.Point(13, 40);
// Handle click event anonymously. btnDumpToFile.Click += delegate { if(TypeDumper.DumpTypeToFile(txtTypeName.Text)) MessageBox.Show(string.Format( "Data saved into {0}.txt", txtTypeName.Text)); else MessageBox.Show("Error! Can't find that type..."); }; Controls.Add(btnDumpToFile);
// Configure the TextBox. txtTypeName.Location = new System.Drawing.Point(13, 13); txtTypeName.Size = new System.Drawing.Size(341, 20); Controls.Add(txtTypeName); } } }
To compile this Windows Forms application using a response file, create a file named WinFormsClientApp.rsp, and add the following commands:
/target:winexe /out:WinFormsClientApp.exe /r:CorLibDumper.dll /r:System.Windows.Forms.dll /r:System.Drawing.dll WinFormsClientApp.cs
Now make sure this file is saved in the same folder as your example code, and supply this response file as an argument to mcs (using the @ token):
1579
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
msc @WinFormsClientApp.rsp Finally, run your Windows Forms application using Mono:
mono WinFormsClientApp.exe
Figure B-8 shows a possible test run.
Figure B-8. A Windows Forms Application Built Using Mono
Executing Your Windows Forms Application Under Linux So far, this appendix has shown you how to create a few assemblies that you could also have compiled using the Microsoft .NET Framework 4.0 SDK. However, the importance of Mono becomes clear when you view Figure B-9, which shows the same exact Windows Forms application running under SuSe Linux. Notice how the Windows Forms application has taken on the correct look and feel of my current desktop theme.
Figure B-9. Executing the Windows Forms Application Under SuSe Linux
■ Source Code You can find the CorLibDumper project under the Appendix B subdirectory.
The preceding examples shows how you can compile and execute the same exact C# code shown during this appendix on Linux (or any OS supported by Mono) using the same Mono development tools. In fact, you can deploy or recompile any of the assemblies created in this text that do not use .NET 4.0 programming constructs to a new Mono-aware OS and run them directly using the Mono runtime utility. Because all assemblies contain platform-agonistic CIL code, you do not need to recompile the applications whatsoever.
1580
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
Who is Using Mono? In this short appendix, I’ve tried to capture the promise of the Mono platform in a few simple examples. Granted, if you intend only to build .NET programs for the Windows family of operating systems, you might not have encountered companies or individuals who actively use Mono. Regardless, Mono is alive and well in the programming community for Mac OS X, Linux, and Windows. For example, navigate to the /Software section of the Mono website: http://mono-project.com/Software
At this location, you can find a long-running list of commercial products built using Mono, including development tools, server products, video games (including games for the Nintendo Wii and iPhone), and medical point-of-care systems. If you take a few moments to click the provided links, you will quickly find that Mono is completely equipped to build enterprise-level, real-world .NET software that is truly cross-platform. Suggestions for Further Study If you have followed along with the materials presented in this book, you already know a great deal about Mono, given that it is an ECMA-compatible implementation of the CLI. If you want to learn more about Mono’s particulars, the best place to begin is with the official Mono website (www.mono- project.com). Specifically, you should examine the page at www.mono-project.com/Use, which serves an entry point to a number of important topics, including database access using ADO.NET, web development using ASP.NET, and so on. I have also authored some Mono-centric articles for the DevX website (www.devx.com) that you might find interesting: • “Mono IDEs: Going Beyond the Command Line”: This article examines many Mono-aware IDEs. • “Building Robust UIs in Mono with Gtk#”: This article examines building desktop applications using the GTK# toolkit as an alternative to Windows Forms. Finally, you should familiarize yourself with Mono’s documentation website (www.go- mono.com/docs). Here you will find documentation on the Mono base class libraries, development tools, and other topics (see Figure B-10).
1581
APPENDIX B ■ PLATFORM-INDEPENDENT .NET DEVELOPMENT WITH MONO
Figure B-10. The Online Mono Documentation
■ Note The website with Mono’s online documentation is community supported; therefore, don’t be too surprised if you find some incomplete documentation links! Given that Mono is an ECMA-compatible distribution of Microsoft .NET, you might prefer to use the feature-rich MSDN online documentation when exploring Mono.
Summary The point of this appendix was to provide an introduction to the cross-platform nature of the C# programming language and the .NET platform when using the Mono framework. You have seen how Mono ships with a number of command-line tools that allow you to build a wide variety of .NET assemblies, including strongly named assemblies deployed to the GAC, Windows Forms applications, and .NET code libraries. You’ve also learned that Mono is not fully compatible with the .NET 3.5 or .NET 4.0 programming APIs (WPF, WCF, WF, or LINQ) or the C# 2010 language features. Efforts are underway (through the Olive project) to bring these aspects of the Microsoft .NET platform to Mono. In any case, if you need to build .NET applications that can execute under a variety of operating systems, the Mono project is a wonderful choice for doing so.
1582
■ ■ ■
Index
overloadability, 445 ■SPECIAL CHARACTERS overloading, 453 * pointer-centric operator, 479 AND NUMERICS *= operator, 445 - (dash) symbol, 44 . (dot) prefix, 655 - operator, 445, 452 "." notation, 779 -- operator /? flag, 565 CIL representation, 452 / operator, 445 overloadability, 445 /= operator, 445 overloading, 449 /addmodule flag, 551 -? option, 663 /checked flag, 110, 111 - pointer-centric operator, 479 /clrheader flag, 535 -- pointer-centric operator, 479 /connectionstring: option, 962 - unary operator, 445 /debug flag, 663 ! operator, 121 /dll flag, 663 != operator, 102, 120, 163, 445, 450, 452 /exe flag, 664 != pointer-centric operator, 479 /FalseString property, 93 # character, 47 /GODMODE value, 1139 % operator, 431, 445 /headers flag, 534 <%@Assembly%> directives, 1398, 1402, /i option, 565 1403 /key flag, 664 %= operator, 445 /keyf option, 575 %ERRORLEVEL% variable, 76 /keyfile option, 562 %FlowDocument> element, 1228 /l option, 565 & (ampersand) suffix, 23, 677 /language: option, 962 & operator, 445, 482 /ldl option, 576 & pointer-centric operator, 479 /main option, 74 & symbol, 1094 /mode:FullGeneration option, 961 && operator, 121, 506 /noconfig option, 48 &= operator, 445 /nostdlib option, 45 * operator, 482 /out flag, 44, 575, 1569 CIL representation, 452 /out option, C# compiler, 44, 551
1583
INDEX ■
/output flag, 664 | operator, 445 /out:TestApp.exe flag, 48 || operator, 121 /pluralize option, 962 |= operator, 445 /project: option, 961 ~ (tilde symbol), 303 /r flag, 45, 46, 48 ~ operator, 445 /r option, 49 ~/ prefix, 1446 /reference flag, 45, 48, 1569 + (plus) operator, 23, 99, 100, 1094 /reference option, 57 + (plus token), 589 /t flag, 44 + binary operator, 445, 447 /target flag, 44, 550, 1514, 1569 + operator, 452 /target:exe option, 44, 1514 + pointer-centric operator, 479 /target:library option, C# compiler, 44 + symbol, 99 /target:module option, C# compiler, 44 + unary operator, 445 /target:winexe option, 44, 1149, 1514 ++ operator /t:exe flag, 44 CIL representation, 452 /t:library option, 551 overloadability, 445 /u option, 565 overloading, 449 /unsafe flag, 480 ++ pointer-centric operator, 479 ? operator, 137 += and -+ operator overloading, 448 ?? operator, nullable types, 164—165 += operator, 408, 409 ? suffix, 162, 163 CIL representation, 452 ? token, 115 overloadability, 445 [ ] (index operator), accessing items from += syntax, 423, 428 arrays, 439 < operator, 120, 452 \" escape character, 100 < pointer-centric operator, 479 \\ escape character, 100 <%@Page%> directive, 1401, 1402, 1403, \" escape character, 101 1409, 1411, 1424, 1443, 1449, 1469, \\ escape character, 101 1477 \a escape character, 100 <<= operator, 445 \gac directory, 1575 << operator, 445 \Images folder, 1287 <= operator, 120, 445, 452 \n escape character, 101 <= pointer-centric operator, 479 \r escape character, 101 < operator, 445 \SQLEXPRESS token, 854 -= operator, 422, 445, 452 \t escape character, 101 =< operator, 437 ^ operator, 445 == operator, 120 ^= operator, 445 CIL representation, 452 __VIEWSTATE field, 1392, 1476, 1477, overloadability, 445 1478, 1479 overloading, 450 __?VIEWSTATE form field, 1478 == operetor, 102 _contentLoaded member variable, 1150, == pointer-centric operator, 479 1151 => pointer-centric operator, 479 _Default class, 1409, 1410 >, 445 _Exception interface, 262 -> operator, 484 { and } tokens, 210 >= operator, 120, 452
1584
INDEX ■
>> operator, 445 AcceptAllChanges( ) method, 959 >>= operator, 445 AcceptButton property, 1529, 1541 > operator, 120 AcceptChanges( ) method, 888, 889, 893, > pointer-centric operator, 479 895, 896 -> pointer-centric operator, 479 access modifiers, 303 0 (integer), 1335 default, 193 0x prefix, 675 and nested types, 194 0X58 opcode, 656 overview, 192 0X59 opcode, 656 accessing profile data programmatically, 0X73 opcode, 656 1505—1507 2D arrays, 443 accessor method, 194, 195, 196, 198, 200, 2D geometric objects, 1246 206 2D graphical data, 1119, 1254 Accessories menu option, 43 2D graphics, 1120 accessors and mutators, for encapsulation 2D vector images, 1254, 1271 of classes, 195—197 3D animation, 1118 Account property, 1065 3D functionality, 1118 ACID (Atomic, Consistent, Isolated, 3D graphical data, 1119 Durable), 878 3D graphics, 1120 action attribute, 1384, 1390, 1417 100% C# code, 1139 Action<> delegate, 771 100% code approach, 1078 Action
1585
INDEX ■
Activity Library project, 1103 Add State Group button, 1367
1586
INDEX ■
AddServiceEndpoint( ) method, 1040, data provider factory model 1051, 1063
1587
INDEX ■
Ads.xml file, 1447, 1448 animated styles, WPF, 1318 Advanced button, 110, 1067 Animation classes, 1304, 1305, 1308 Advanced Properties button, 1301 animation editor mode, 1360 Advanced properties square, 1297 Animation elements, 1310 Advanced Property options, 1236 Animation objects, 1308, 1309 AdvertisementFile property, 1447, 1448 animation services, WPF Age property, 200, 379, 384 Animation class types, 1304—1305 Aggregate
1588
INDEX ■
overview, 473 creating ToString( ) and GetHashCode( ), 476 loading assemblies into custom AnonymousMethods project, 430 application domains, 645 AnonymousTypes project, 474, 479 overview, 643—644 Any( ) method, 1107 programmatically unloading API (application programming interface), AppDomains, 646—648 1013, 1014, 1015, 1016, 1017, 1391— default, interacting with, 640—643 1395 overview, 637—639 API (CardSpace application programming System.AppDomain class, 638—639 interface), 1023, 1030 AppDomains (application domains), API (C/Windows application programming defined, 625 interface), 4 Append member, FileMode enumeration, API (Simple application programming 787 interface)XML ( for Extensible AppendText( ) method, FileInfo class, 785, Markup Language)SAX (), 993 789 API (Windows Application Programming AppExit( ) method, 1137 Interface), 260, 285, 286, 729 application cache API features data caching, 1489—1491 1.0-1.1, 1392—1393 modifying *.aspx file, 1491—1493 2.0, 1393—1394 overview, 1488 3.5 (and .NET 3.5 SP1), 1394 Application class, 1138, 1139, 1144, 1145 4.0, 1394—1395 Application.Windows collection, overview, 1391 enumerating, 1130 App_Browsers subdirectory, 1414 constructing, 1129—1130 App_Code directory, 1415 overview, 1128 App_Code folder, 1072, 1414, 1415 Application Component Object Model App_Code subdirectory, 1414 (COM) object, 1483 App_Data folder, 1415, 1440, 1503, 1506, application data, modifying, 1486—1487 1508 Application -derived class, 1137 App_Data subdirectory, 1414, 1503 application directory, 553 App_GlobalResources subdirectory, 1414 application domains (AppDomains), App_LocalResources subdirectory, 1414 defined, 625 App_Theme folder, 1466, 1469 application error code, C# programming, App_Themes folder, 1415, 1465, 1466, 1467 76—77 App_Themes subdirectory, 1414 Application markup, 1350 App_WebReferences subdirectory, 1414 application object, 73, 74, 1129 App.config file, 557, 558, 849, 852, 857, 871, application programming interface (API), 932, 984, 986, 1037 1013, 1014, 1015, 1016, 1017, 1391— AppConfigReaderApp application, 578, 579 1395 AppDomain shutdown, 304 Application property, 1416, 1482, 1483, AppDomain.CreateDomain( ) method, 643 1485 AppDomain.DefineDynamicAssembly( ) application resources, embedding, 1289— method, 693 1291 AppDomain.Load( ) method, 645 application roots, and object lifetime, 294— AppDomains (application domains) 295
1589
INDEX ■
application shutdown, handling, 1488 implementing Tools menu application state functionality, 1555—1556 handling web application shutdown, main menu system, 1552—1553 1488 populating controls collection, maintaining application-level state 1515—1517 data, 1484—1486 ShapeData type, 1553 modifying application data, 1486—1487 ShapePickerDialog type, 1553—1555 overview, 1483 System.EventArgs and Application tab, 74, 531, 565, 571, 919, System.EventHandler, 1517—1518 1144, 1514 client, building, 1046—1050 Application type, 1121, 1522 composition of, 1025—1027 application variable, web-based, 1124 web, 1380—1382 Application_End( ) method, 1481, 1488 Applications folder, 1572 Application_Error( ) event, 1481, 1482 Applications tab, 984 Application_Start( ) event, 1481, 1485, Application.Windows collection, 1489, 1490 enumerating, 1130
1590
INDEX ■
arithmetic operations, 756 AsParallel( ) method, 771 Array class, 519 AsParallel( )method, 772 Array object, 513 AsParallel( ) method, 772 Array of [T] option, 1098
1591
INDEX ■
defining user profiles within client-side scripting, 1388—1390 Web.config, 1504—1505 HTTP grouping profile data and persisting request/response cycle, 1380 custom objects, 1507—1509 stateless protocols, 1380 overview, 1502 Hypertext Markup Language (HTML) role of
1592
INDEX ■
referencing AutoLotDAL.dll overview, 33 assembly, 1409 viewing assembly metadata, 35 updating code file, 1409—1410 viewing Common Intermediate Web applications and servers Language (CIL) code, 34 ASP.NET development web server, viewing type metadata, 34 1382 exploring using Reflector, 35—36 IIS virtual directories, 1381 external, 536, 1081 overview, 1380 friend, 545 Web site directory structure interop, 714, 717 App_Code folder, 1415 interoperability, 714, 716 overview, 1413 loaded referencing assemblies, 1414—1415 enumerating, 641—642 Web sites and Web applications, 1412— receiving assembly load 1413 notifications, 643 Web.config files, 1427—1428 loading, 553, 645 ASP.NET Web Service template, Visual localized, 598 Studio, 1017 metadata, 17—18 aspnet_compiler.exe tool, 1410, 1427 multi-file, 14 aspnet_regsql.exe, 1503 production-ready, 1562 aspnet_state.exe, 1500, 1501 referencing external, 32, 1414—1415 aspnet_wp.exe, 1500 with csc.exe, 45—46 AspNetCarsSite application, 1456 with Visual Studio 2010, 57 AspNetCarsSite project, 1442 resource-only, defining, 1300—1301 AspNetCarsSite website, 1457 shared, 598—600 ASPNETDB.mdf database, 1503—1504, single-file, 14 1506, 1507, 1508, 1509 workflow, importing, 1105
1593
INDEX ■
Assembly table, 585 assigning themes programmatically, 1469— assembly token, 585, 1159 1471 Assembly type, 596 Associations folder, 983 Assembly Version number, 571 AsyncCallback delegate, 736—738, 1069 [assembly:] tag, 612 AsyncCallback object, 736
1594
INDEX ■
CIL, 655 creating inventory table, 840—842 custom visually creating table relationships, applying, 610 846—847 named property syntax, 610—611 AutoLot database icon, 849 overview, 609 AutoLot project, 917 restricting usage, 611—612 AutoLotConnDAL.cs file, 862 using early binding, 614—615 AutoLotConnectedLayer class, 1409 using late binding, 615—617 AutoLotConnectedLayer namespace, 862, using to customize serialization, 823 882, 1073, 1398, 1402, 1492 XAML, 1160—1161 AutoLotCUIClient application, 871, 877, Attributes( ) method, 1000 882 Attributes property, FileSystemInfo class, AutoLotDAL (Version 2) project, 920 778 AutoLotDAL (Version 3) project, 940 AttributeTargets enumeration, 611 AutoLotDAL Code Library project, 880 [AttributeUsage] attribute, 611, 612 AutoLotDAL namespace, 984, 986, 1242
1595
INDEX ■
AutoLotDisconnectionLayer namespace, BAML (Binary Application Markup 862 Language), transforming markup AutoLot.dll assembly, 927, 938, 940, 984, into .NET assembly, 1151—1152 1105, 1106, 1112 *.baml file extension, 1151, 1152 autoLotDS object, 924 base addresses, specifying, 1038—1040 AutoLotEDM_GUI application, 986 base classes AutoLotEDMClient application, 984 casting rules AutoLotEDMClient example, 986 is keyword, 250 AutoLotEntities class, 954, 959, 970, 971, as keyword, 249 974 overview, 247—248 AutoLotInventory variable, 1106 controlling creation of with base AutoLot.mdf file, 189 keyword, 228—230 AutoLotService project, 1076 libraries, role of in .NET, 8 AutoLotService.cs file, 1073 multiple, 222 AutoLotWCFService class, 1071 base keyword, 229, 237, 254, 654, 1482 automatic properties
1596
INDEX ■
beforefieldinit item, 611 binary format, serializing Begin method, 1035, 1069 DataTable/DataSet objects in, BEGIN TRANSACTION statement, 878 902—903 BeginAnimation( ) method, 1307, 1309 binary operator overloading, 445—447 BeginCatchBlock( ) method, 690 binary resources, WPF BeginClose( ) method, 1040 embedding application resources, BeginEdit( ) method, 893, 896 1289—1291 BeginExceptionBlock( ) method, 690 loose resources BeginFinallyBlock( ) method, 690 configuring, 1287 BeginInvoke( ) method, 399, 400, 732, 734, including files in project, 1286—1287 736, 738, 760, 774, 1086 overview, 1285 Beginner's All-purpose Symbolic programmatically loading images, Instruction Code (BASIC), 997 1288—1289 BeginOpen( ) method, 1040 BinaryCars.bin file, 903 BeginScope( ) method, 690 BinaryFormatter class, 529, 606, 807, 808,
1597
INDEX ■
DataTable objects to Windows Forms Blend window, 1211 GUIs Blend XAML editor, 1210 DataView type, 912—913 block elements, Documents API, 1227 deleting rows from DataTable, 907— Blocks (Collection) property, 1230 908 Blocks editor, 1230 hydrating DataTable from generic BlockUIContainer element, 1227 List
tag, 1435 Blend Resources window, 1321
1598
INDEX ■
bread crumbs, establishing with btnShowLogicalTree object, 1342 SiteMapPath type, 1447 btnShowVisualTree control, 1343 breadcrumbs technique, 1447 btnSpin control, 1371 break keyword, 117, 122 btnSpinner object, 1307 brower statistics, obtaining, 1419 btnSubmit button, 1505 Browse For Types option, 1095, 1106, 1107 btnUpdateDatabase class, 921 Browse tab, 57, 541, 546, 567 btnUpdateInventory control, 937 Browser property, 1418, 1419 bubbling events, 1337, 1339 Brush editors, 1171, 1260, 1269—1271, 1301 BufferedGraphics type, 1547 Brush object, 1248 BufferedStream class, 776 Brush type, 1269, 1547, 1550 BufferHeight property, System.Console brushes class, 82 configuring in code, 1260—1261 BufferWidth property, System.Console configuring using Visual Studio 2010, class, 82 1258—1260 bugs, 259—260 Brushes area, 1269 Build a Car menu item, 1447 Brushes class, 1550 Build a Car node, 1446 Brushes editor, 1222, 1269, 1358 Build Action property, 1287, 1289, 1292 Brushes type, 1547 Build menu, Visual Studio 2010, 1290 BSTR data type, 7 Build tab, 110, 657 btnAddWidgets control, 1435 build tools, automated, 43 btnCancel button, 1538 Build-a-Car, designing content page, btnCancel control, 771, 772 1455—1457 btnChangeMakes class, 911 BuildCar.aspx, 1446 btnClear control, 1226 BuildMenuSystem( ) method, 1516 btnClearPanel control, 1436 BuildTableRelationship( ) method, 923, btnDisplayMakes class, 908 924 btnDownload control, 768 Bukovics, Bruce, 1077 btnExecute control, 771 business process, defining role of WF 4.0 btnExitApp variable, 1150 in, 1078 btnExitApp_Clicked( ) method, 1150 >> button, 1212, 1213 btnGetCar button, 1474 Button class, 920, 921, 1396, 1397, 1398, btnGetOrderInfo class, 925 1399, 1408, 1409, 1422, 1423 btnGetStats control, 768 Button Click event, 1431 btnGetStats_Click( ) method, 770 Button controls, 718, 768, 1198, 1226, 1292, btnGetTextData control, 1436 1315, 1318, 1319, 1342, 1469 btnLoad control, 1226 Button element, 1160, 1202, 1338 btnOK button, 1538 Button object, implementing Click event, btnPostback button, 1477 1175—1176 btnReset class, 1387 Button property, 1534, 1535 btnSave control, 1226 Button skin, 1469 btnSetCar button, 1474 Button template, 1366 btnShow class, 1387, 1389 Button type, 1146, 1159, 1164, 1173, 1175, btnShowAppVariables button, 1486 1341, 1467, 1469 btnShowCarOnSale button, 1486
1599
INDEX ■
1600
INDEX ■
overview, 418 implicitly typed local, 139 registrating, simplifying using Visual initialization syntax, 138 Studio 2010, 423—424 multidimensional, 140—141 indexer methods of objects, 139—140 definitions on interface types, 444 overview, 137 multiple dimensions, 443—444 as return values, 142 overloading, 443 System.Array class, 142—144 overview, 439—440 command-line arguments, 77—79 string values, 441—442 data type conversions LINQ query operators narrowing data conversions, 108— aggregation operations, 516—517 110 basic selection syntax, 510—511 overflow checking, 110—111 LINQ as better Venn diagramming overview, 106—107 tool, 515—516 System.Convert, 112 obtaining counts using enumerable, unchecked keyword, 111 513 enum type obtaining subsets of data, 511 declaring variables, 146—147 overview, 508—509 discovering name/value pairs of, projecting new data types, 512—513 148—150 removing duplicates, 516 overview, 144 reversing result sets, 514 System.Enum type, 147 sorting expressions, 514 underlying storage for, 145—146 operator overloading if/else statement, 120 += and -+, 448 implicitly typed local variables binary, 445—447 are strongly typed data, 115 comparison, 450 overview, 112—113 equality, 449—450 restrictions on, 114—115 internal representation of, 451—452 usefulness of, 116 overview, 444 iteration constructs unary, 448—449 do/while loop, 119 pointer types foreach loop, 118 * and & operators, 482 for loop, 117 field access with pointers, 484 while loop, 119 overview, 479—480 methods pinning types with fixed keywords, default parameter-passing behavior, 485—486 126—127 sizeof keyword, 486 named parameters, 133—134 stackalloc keyword, 485 optional parameters, 131—132 unsafe (and safe) swap function, 483 out modifier, 127—128 unsafe keyword, 481—482 overloading of, 135—137 C# programming constructs, 73—123, 125— overview, 125 165 params modifier, 130—131 application error code, 76—77 ref modifier, 128—129 arrays nullable types as arguments, 142 ?? operator, 164—165
1601
INDEX ■
overview, 162 C++ function pointer, 397 working with, 163—164 C++/Microsoft Foundation Classes (MFC), reference types 4 passing by reference, 160 cache application Graphical User Interface passing by value, 158—160 (GUI), 1492 string data Cache object, 1489, 1490 basic manipulation, 98—99 Cache property, 1416, 1421, 1489 concatenation, 99—100 Cache type, 1493 escape characters, 100—101 Cache variable, 1490 overview, 97 CacheDependency object, 1491 strings and equality, 102 CacheItemRemovedCallback delegate, strings are immutable, 102—104 1491, 1493 System.Text.StringBuilder type, Cache.NoAbsoluteExpiration field, 1491 104—105 Cache.NoSlidingExpiration field, 1491 verbatim strings, 101—102 Cache.NoSlidingExpiration parameter, structure type, 151—153 1491 switch statement, 121—123 CacheState project, 1489 system data types Calc class, 14, 15, 17 class hierarchy, 90—92 Calc.Add( ) method, 34 and new operator, 89—90 Calc.cs file, 16, 18, 33 numerical data types, 92 Calc.exe application, 35 overview, 86—87 Calc.exe assembly, 33 parsing values from string data, 94 Calc.exe file, 18, 19 System.Boolean, 93 CalculateAverage( ) method, 130, 131 System.Char, 93—94 Calc.vb code file, 16 System.DateTime, 95 Calendar control, 1439, 1455 System.Numerics, 95—97 Calendar type, 1467 System.TimeSpan, 95 call opcode, 678, 690 variable declaration, 88—89 callback functions, 397 System.Console class CallbackContract property, 1034 basic input and output with, 82—83 callbacks, 397, 398 formatting numerical data, 84—85 calling tier, 885, 886 formatting output, 83 CallMeHere( ) method, 413 overview, 81 callvirt opcode, 690 System.Environment class, 79—81 Cancel button, 1294, 1296, 1297 value types Cancel( ) method, 772, 858 containing reference types, 157—158 Cancel property, 1141 overview, 154 cancelation request, 766—767 vs. reference types, 155—156, 161— CancelButton property, 1529, 1541 162 CancelEdit( ) method, 893 variations on Main( ) method, 75—76 CancelEventArgs class, 1141 C# Snap-In, 619—620 CancelEventArgs.Cancel property, 1141 C# Windows Application solution, 51 CancelEventHandler delegate, 1141 C++ Component Object Model (COM) cancellation tokens, 766 developers, 260 CancellationScope activity, WF 4.0, 1092
1602
INDEX ■
CancellationToken property, 767 CarDelegateMethodGroupConversion CancellationTokenSource class, 766 application, 412 CancellationTokenSource object, 766, 772 CarDelegateMethodGroupConversion CancellationTokenSource token, 767 project, 413 cancelToken object, 772 CarDelegateWithLambdas project, 437 cancelToken variable, 766 CardSpace application programming CanExecute attribute, 1205 interface (API), 1023, 1030 CanExecute event, 1203, 1205 CarEngineHandler class, 406 CanExecute handler, 1205 CarEngineHandler delegate, 408, 420, 425 CanExecute property, 1205 CarEngineHandler objects, 418 CanExecuteRoutedEventArgs object, 1205 carErrors.txt file, 281 CanHelpExecute( ) method, 1204 CaretIndex property, 1200 CanRead member, Stream class, 792 CarEventArgs class, 425 CanSeek member, Stream class, 792 CarEventArgs type, 425 Canvas area, 1186 CarEvents application, 420 Canvas class, 1138, 1162, 1250, 1252 CarEvents example, retrofitting using Canvas object, 1252, 1264, 1276 lambda expressions, 436—437 Canvas panels, 1186—1188 CarEvents project, 424 Canvas scope, 1339 CarExploded( ) method, 428 Canvas type, 1188 car.gif file, 1448
1603
INDEX ■
CarLibrary.exe file, 554 Channel property, 1046 CarLibraryPolicy.xml file, 575 char array, 98 CarLocator class, 471, 472 char data type, 87 CarLotInfo class, 1485 char keyword, 93 CarNickname property, 969, 971 char variable, 89 CarOrderApp project, 1538, 1545 character data, 102 Cars property, 955, 971, 974 Check button, 1196, 1198 Cars web site, building Check for arithmetic overflow/underflow defining default content pages, 1448— check box, 110 1449 CheckBox control, 1235, 1431 designing Build-a-Car content page, Checked event, 1220 1455—1457 checked keyword, 73, 108, 109, 110, 111 designing Inventory content pages, Checked property, 1554 1450—1452 CheckInventoryWorkflowLib project, 1103 enabling in-place editing, 1454 CheckInventoryWorkflowLib.dll assembly, enabling sorting and paging, 1453 1112 master pages CheckInventory.xaml file, 1103 AdRotator widget, 1447—1448 Cherries.png file, 1358 bread crumbs, establishing with child class, 189 SiteMapPath type, 1447 ChildRelations member, 897 overview, 1442—1444 Choose Data Source dropdown box, 927, TreeView control site, 1445—1447 986, 1451 overview, 1441 CIL. See common intermediate language Cars.cd file, 224 CILCar argument, 686 carsDataSet.xml file, 901 CILCar class, 684 cascading style sheet (CSS), 1394 CILCar object, 687 case-sensitive languages, 74 CILCar parameter, 685 CaseSensitive member, 897 CILCarInfo class, 685 CaseSensitive property, 887 CILCarInfo.Display( ) method, 686 casting operations, 247, 366, 1107 CilCars example, 688 catch blocks, 267, 273, 277, 278, 279, 280, CILCars namespace, 684, 685 690 CILCars.dll assembly, 686 catch keyword, 109, 249, 261 CILCars.il file, 683 catch logic, 268, 270, 271, 277, 281 CILTypes assembly, 667 catch scope, 274, 278, 279, 281 CilTypes example, 683 catching exceptions, 266—267 CILTypes.il file, compiling, 672—673 CDATA scope, 1147 Circle class, 191, 244, 324, 328, 525 CDATA section, 1390 Circle type, 243, 246 CenterToScreen( ) method, 1530 circleOption RadioButton, 1251 -centric dot notation, 667 Class attribute, 1146, 1177 ceq opcode, 678 class constructor, 675 CGI applications, 1475 Class Designer. Name, 66 cgt opcode, 678 Class Designer Toolbox, 65, 66, 225 Change Layout Type menu option, 1211 Class Details window, 65, 66, 225 ChangeDatabase( ) method, 855 Class Diagram icon, 224
1604
INDEX ■
Class Diagram viewer, 65 internal representation of .class directive, 655, 660, 668, 669, 670, 677 properties, 202—203 class extern tokens, 551 overview, 194 class hierarchy, of system data types, 90— read-only and write-only properties, 92 204—205 Class icon, 167 static properties, 205—206 class keyword, 19, 167, 1158 using .NET properties, 198—200 class libraries, isolating strongly typed using properties within class database code into definition, 200—201 deleting data with generated codes, using traditional accessors and 942—943 mutators, 195—197 inserting data with generated codes, visibility levels of properties, 204 941—942 new keyword, 170 invoking stored procedures using object initializer syntax generated codes, 943 calling custom constructors with, overview, 938 212—213 selecting data with generated codes, inner types, 213—214 940—941 overview, 210—211 viewing generated codes, 939—940 and optional arguments, 180—181 Class Library project, 538, 547, 937, 939 overview, 167 class library relationship, 8 partial types, 217—218 Class Library template, 1023 static keyword Class member, 695 classes, 187—188 class token, 677 constructors, 185—187 class types field data, 182—185 access modifiers methods, 181—182 default, 193 this keyword and nested types, 194 chaining constructor calls using, overview, 192 176—178 automatic properties and constructor flow, 178—181 and default values, 208—210 overview, 174—175 interacting with, 208 Class View tool, 59, 939 overview, 206—207 Class View utility, Visual Studio 2010, 58— Common Type System (CTS), 19 59 constant field data Class View window, 970 constants, 214—216 Class1.cs, 711 read-only fields, 215—216 ClassDiagram1.cd file, 224 static read-only fields, 216 classes constructors abstract, 240 custom, 172 allocation onto managed heap, 291 default, 171—173 characteristics of, 19, 20 overview, 170 creating instances of, 291 conversions, 454—455 custom, 204 defining in CIL, 668—669 generic encapsulation services
1605
INDEX ■
default keyword in generic code, clients, invoking services asynchronously 390—391 from, 1067—1069 generic base classes, 391—392 client-side scripting, 1388—1390 overview, 388—389 ClientTarget property, 1416 specifying type parameters for, 372— Clip property, 1255 374 ClipGeometry property, 1255 sealed, 232 ClipToBounds property, 1265 classical inheritance, 220 Clone( ) method, 323, 350, 351, 352, 353, ClassModifier keyword, 1156, 1159 354, 888 clean entities, 990 cloneable objects, building, 349—354 Clean Solution option, Visual Studio 2010, CloneablePoint application, 349 1290 CloneablePoint project, 354 CleanUp( ) method, 311 CloneableType class, 323 Clear( ) method, 82, 143, 888, 1421, 1484, CloneMe( ) method, 323, 331 1515, 1548 cloning, 349 Clear Surface menu handler, 1556 Close( ) member ClearCollection
1606
INDEX ■
code file model, 1401 applying LINQ queries to nongeneric code files collections, 507—508 building Web pages using, 1406—1411 filtering data using OfType element, 1147 collections CodeActivity activity, 1109 nongeneric, applying LINQ queries to, CodeActivity
1607
INDEX ■
frameworks, 889 command-line arguments, C# interfaces, 261 programming, 77—79 objects, 1483 command-line compiler, 537, 550, 552 programming language comparison, 5— command-line parameters, 43, 76 6 CommandText property, 858, 867, 870 servers, 5 CommandTimeout member, 858 COM (Session Component Object Model) CommandTimeout property, 959 object, 1483 CommandType enum, 858 COM interoperability CommandType property, 858 simplifying using dynamic data CommandType.StoredProcedure value, common COM interop pain points, 870 717—718 Commit( ) method, 879, 882 embedding interop metadata, 716— COMMIT statement, 878 717 committed transactions, 878 overview, 714 Common Controls section, 1544 role of Primary Interop Assemblies common dialog boxes category, 1512 (PIAs), 715 common intermediate language (CIL) using C# 4.0 language features, 718—724 .NET base class library, C#, and CIL without C# 4.0 language features, 722— data type mappings, 673 724 and assemblies COM+ layer, 1016 benefits of, 16—17 COM+ objects, 1015, 1022 compiling to platform-specific COM+/Enterprise Services, 1015 instructions, 17 Combine menu, 1268 overview, 14—15 Combine( ) method, 401 attributes, role of, 655 CombinedGeometry class, 1255 building .NET assembly with ComboBox control, Ink API tab, 1224—1226 building CILCarClient.exe, 686—687 ComboBoxItem control, 1218, 1225 building CILCars.dll, 683—686 ComboBoxItem objects, 1219, 1225 compiling CILTypes.il file, 672—673 comboColors control, 1219 defining and implementing interfaces comContracts element, 1042 in, 670 comma-delimited list, 130, 393 defining class types in, 668—669 command builder type, 918 defining current assembly in, 667 command line, generating strong names defining enums in, 671 at, 561—563 defining field data in, 674—675 Command object, 827, 828, 834 defining generics in, 671—672 command prompt defining member parameters, 676—677 Mono, 1568, 1572, 1577 defining namespaces in, 668 Visual Studio 2010, 33, 534 defining properties in, 676 Command property, connecting WPF defining structures in, 670—671 commands to, 1202—1203 defining type constructors in, 675 CommandBinding objects, 1203 defining type members in, 674—677
1608
INDEX ■
opcodes data types, 22—23 .maxstack directive, 680 delegate types, 21—22 declaring local variables in CIL, 680— enumeration types, 21 681 interface types, 20 hidden this reference, 682 structure types, 20 mapping parameters to local type members, 22 variables in CIL, 681 commonBehaviors element, 1042 overview, 677—679 CommonSnappableTypes namespace, 621 representing iteration constructs in CommonSnappableTypes.dll assembly, CIL, 682—683 618, 619, 621, 622 role of, 655 CommunicationState enumeration, 1041 overview, 653 Company property, 206 reasons for learning grammar of, 653— [CompanyInfo] attribute, 619, 623 654 CompanyInfoAttribute attribute, 619 round-trip engineering companyName field, 206 authoring CIL code using comparable objects, building SharpDevelop, 665—666 custom properties, custom sort types, compiling CIL code using ilasm.exe, 358 663—664 overview, 354—356 interacting with CIL, 662—663 specifying multiple sort orders overview, 658—660 (IComparer), 357—358 role of CIL code labels, 661—662 ComparableCar application, 355 role of peverify.exe, 666 ComparableCar project, 359 specifying externally referenced Compare( ) method, 97, 383 assemblies in, 666 CompareExchange( ) method, Interlocked stack-based nature of, 656—658 class, 756 Common Language Infrastructure (CLI) CompareTo( ) method, 355, 356 mainstream distributions, 1563—1564 CompareValidator control, 1458 role of, 1562—1563 CompareValidator type, 1459 Common Language Runtime (CLR) CompareValidator widget, 1461—1462 data type, 1504 comparison operator overloading, 450 defined, 25—26 CompensableActivity activity, WF 4.0, 1092 property wrappers, 1325, 1326, 1328, Competed event, 1091 1330 compilation cycle for multifile pages, 1410 Common Language Specification (CLS), 3, compilation cycle for single-file pages, 7, 23—25, 605, 612 1405—1406 Common Object Request Broker
1609
INDEX ■
Component, 1301 connection string, 854, 856 Component Object Model. See COM Connection String property, 849 component tray, 931 connection timeout setting, 855 ComponentCommands class, WPF, 1201 ConnectionState enumeration, 855, 856 components category, 1512 ConnectionState values, 856 composition, of applications, 1025—1027 ConnectionState.Closed value, 856 Concat( ) method, 516 ConnectionState.Open value, 856 concatenation, of string data, 99—100 connectionString attributes, 852 concatenation symbol, 1094 ConnectionString property, 849, 855, 857, conceptual model, 958 1451 concurrency, 728—729, 750—758
1610
INDEX ■
ConstructorBuilder, DefineProperty( ) ContextBoundObject class, 757 method, 696 Context.Cache property, 1488 ConstructorBuilder member, 689 Context.Cache.Insert( ) method, 1490 ConstructorBuilder type, 690, 696 context.Inventories, 1242 constructors ContextMenu property, arguments, 205 FrameworkElement type, 1133 chaining calls, 176—178, 180, 199 contextual boundaries, AppDomain, 625 for classes contextual keyword, 199 custom, 172 continue keyword, 117 default, 171—173 contract element, 1037 overview, 170 contracts definition, single, 180 data, 1070—1076 emitting, 696—697 operational, service types as, 1035—1036 flow of, and this keyword, 178—180 WCF, 1027 static, 185—187 contravariance, 9, 10, 414 contained controls, enumerating, 1432— Control class, 1132, 1314, 1404, 1416, 1512, 1435 1515, 1526—1529 ContainerControl class, 1529 control declarations, ASP.NET, 1403—1404 containers control flow activities, WF 4.0, 1089 generating documents from, 1004—1005 Control Flow area, 1104 type-safe, 367 Control Library section, 1184 ContainerVisual class, 1277 Control Panel, 1500 ContainerVisual object, 1258 Control property, 1537 containment, programming for, 232—235 control templates, WPF containment/delegation model, 190, 219, building custom with Visual Studio 232 2010 Contains( ) method, 97, 98 {TemplateBinding} markup content display area, 1354 extension, 1352—1353 content model, WPF, 1226 ContentPresenter, 1354 content pages incorporating templates into styles, default, 1448—1449 1354—1355 designing, 1455—1457 incorporating visual cues using Content property, 1131, 1132, 1181, 1185, triggers, 1351—1352 1218, 1219, 1236, 1238, 1353, 1354 overview, 1348 ContentControl class, 1117, 1131, 1132, templates as resources, 1349—1351 1181, 1185 default ContentEncoding property, 1421 overview, 1341—1343 ContentPlaceHolderID value, 1449 programmatically inspecting, 1344— ContentPresenter class, 1344, 1352, 1354 1348 ContentProperty class, 1241 Control type, 1132, 1133, 1346, 1437 ContentType property, 1421 control-agnostic events, 1200 context 0 (default context), application ControlBox property, 1529 domain, 648 ControlCollection object, 1432 context attributes, 649 controls. See also ASP.NET web controls Context property, 1489, 1490 collection, populating, 1515—1517
1611
INDEX ■
contained, enumerating, 1432—1435 Copy Local property, 568 created dynamically, 1436—1437 Copy( ) method, 888, 897 dynamically adding and removing, Copy to Output Directory property, 1008, 1435—1436 1287, 1289 dynamically created, 1436—1437 CopyTo( ) method for validation Array class, 143 CompareValidator widget, 1461— FileInfo class, 785 1462 CopyToDataTable
1612
INDEX ■
CreateDomain( ) method, AppDomain CSharpSnapIn project, 619, 620 class, 638 CSharpSnapIn.dll assembly, 618, 621, 623 CreateInstance( ) method, 601, 638 *.csproj file, 1148, 1150, 1151, 1166 CreateMyAsm( ) method, 691, 692, 693, CSS (cascading style sheet), 1394 697 CssClass property, WebControl Base Class, CreateNew member, FileMode 1438 enumeration, 787 CssStyle property, 1465 CreateObject
1613
INDEX ■
CurrentThread property, resolving name clashes with aliases, System.Threading.Thread Class, 528—530 741 resolving name clashes with fully currentVideoGames array, 519 qualified names, 527—528 currentVideoGames variable, 500 custom objects, persisting, 1507—1509 currInterestRate field, 183, 185 .custom tokens, 542, 544 currInterestRate variable, 186 custom type conversions currPay field, Employee class, 196 among related class types, 454—455 currSpeed field, 170, 686 anonymous types Cursor property, 1133, 1198, 1526 containing anonymous types, 478 curves, cubic Bezier, 1257 equality for, 476—478 CustID field, 846 internal representation of, 474—475 CustID key, 846 overview, 473 CustID parameter, 882 ToString( ) and GetHashCode( ), 476 CustID value, 845 creating routines, 455—457 custom attributes explicit conversions for square types, applying, 610 458 named property syntax, 610—611 extension methods overview, 609 extending interface types with, 469— restricting usage, 611—612 470 custom classes, 204, 758 extension libraries, 467—468 custom constructor, 153 importing types that define, 465—466 custom conversion routines, internal IntelliSense mechanism, 466—467 representation of, 460 invoking on instance level, 463 custom event arguments, creating, 424— invoking statically, 464 425 overview, 460—462 custom exceptions, building, 273—276 scope of, 464—465 custom interfaces, defining, 325—327 implicit conversion routines, 458—459 custom layout manager, rendering to, internal representation of custom 1280—1282 conversion routines, 460 custom metadata viewer numerical, 454 displaying various odds and ends, 592 partial methods, 470—473 fields and properties, 591 custom view state data, adding, 1478—1479 generic types, 594 CustomAttribute tokens, 586 implemented interfaces, 591 CustomAttributeBuilder member, 689 implementing Main( ) method, 592—593 CustomBinding class, 1028 method parameters and return values, CustomConversions project, 455, 460 594—595 CustomDepPropApp application, 1331 methods, 590 CustomDepPropApp project, 1337 overview, 590 CustomEnumerator project, 345 custom namespaces, defining CustomEnumeratorWithYield application, creating nested namespaces, 530 346 default namespace of Visual Studio CustomEnumeratorWithYield project, 349 2010, 531
1614
INDEX ■
customers table, creating in AutoLot public point of, 199 database, 844 read-only field, 215 CustomException class, 273 selecting with generated codes, 940— CustomException namespace, 343 941 CustomException project, 273 stack-based, 366 CustomGenericMethods application, 385 data access library, ADO.NET, reusing CustomGenericMethods project, 388 adding connection logic, 863 CustomInterface application, 325 adding deletion logic, 865 CustomInterface project, 335 adding insertion logic, 863—864 customizing Soap/Binary serialization adding selection logic, 866 processes adding update logic, 865 overview, 818—819 executing stored procedure, 869—871 using attributes, 823 overview, 861—862 using ISerializable, 820—822 parameterized command objects, 867— CustomNamespaces application, 525 869 CustomNamespaces namespace, 527 data access logic, adding, 1397—1401 CustomNamespaces project, 531 data adapter class, 913 CustomNamespaces.exe assembly, 525 data adapters CustomSerialization project, 821 configuring using SqlCommandBuilder CustomValidator control, 1458 class, 918—919 CustomVisualFrameworkElement class, mapping database names to friendly 1283 names, 916 CustomVisualFrameworkElement objects, overview, 913 1281 prepping, 922—923 Cut command, 1200 simple data adapter example, 914—915 Cut operation, 1202 strongly typed, 936—937 C/Windows application programming data allocation, in-memory, 183, 184 interface (API), 4 data binding entities, to Windows Forms GUIs, 986— 989 ■D WPF Data Binding tab, 1236 D command, 872 DataContext property, 1239 D string format character, 84 DataGrid tab, 1242—1244 daemon threads, 750 establishing data bindings, 1236— dash (-) symbol, 44 1238, 1241—1242 data IValueConverter interface, data 2D graphical, 1254 conversion using, 1240—1241 deleting with generated codes, 942—943 overview, 1235 inserting with generated codes, 941— Data Binding option, 1236 942 Data Binding tab, WPF, 1214, 1236 interactive graphical, 1246 data caching, 1489—1491 interoperability, 716 Data Connections node, 840 private, 195 data contracts, designing private points of, 207 examining Web.config files, 1075
1615
INDEX ■
implementing service contracts, 1073— data type variable, 90 1074 data types overview, 1070 Common Type System (CTS), 22—23 role of *.svc files, 1074 nullable, 837 testing services, 1075—1076 data validation logic, 210 using Web-Centric service project DataAdapter object, 828 templates, 1071—1073 Database Diagrams node, 846 Data Control Language (DCL), 885 Database Explorer window, 840 Data Definition Language (DDL), 885 Database Management System (DBMS), data parallelism, 763—766 827, 829, 830, 886 data points, 189 database management systems (DBMS), Data property, 270—272, 274, 1101, 1254, 830, 851, 867 1255, 1256, 1257, 1267 database names, mapping to friendly data provider factory model, ADO.NET names, 916
1616
INDEX ■
DataGridView class, 903, 904, 906, 907, DataRow.EndEdit( ) method, 896 912, 920, 921, 924, 927, 928 DataRowExtensions class, 946 DataGridView control, 927—932 DataRowExtensions.Field
1617
INDEX ■
DataTable class, 866, 885, 886, 888, 891, strongly typed, 934 892, 935, 936, 937, 939 dataToShow variable, 1342 DataTable objects, binding to Windows DataType property, DataColumn class, 890 Forms GUIs DataTypeFunctionality( ) method, 93 DataView type, 912—913 DataView class, 885, 912, 913, 949 deleting rows from DataTable, 907—908 DataView object, 904 hydrating DataTable from generic DataView type, 832, 912—913 List
1618
INDEX ■
DecelerationRatio property, Timeline definitions on interface types, 444 class, 1305 Delay activity, WF 4.0, 1091 decimal data type, 87 Delegate, 412 DeclareImplicitVars( ) method, 113 delegate keyword, 21, 398, 399, 400, 401, DeclareLocal( ) method, 690 432 Decrement( ) method, 756, 757 delegate variable, 412 dedicated databases, storing session data Delegate.Combine( ) method, 409, 421 in, 1502 DelegateCovariance application, 413 deep copy, 350 DelegateCovariance project, 415 default application domain, 638 delegate/event model, 9 default constructor, 89, 153, 211, 212, 393 Delegate.Remove( ) method, 410, 421 default content pages, 1448—1449 delegates default context (context 0), application .NET delegate type, 397—398 domain, 648 asynchronous nature of Default edit area, 1107 BeginInvoke( ) and EndInvoke( ) default endpoints, 1051—1052 methods, 732 default input button, setting, 1541 overview, 731 default keyword, 390 System.IAsyncResult interface, 732— Default namespace option, 531 733 Default property, 1106 defining delegate type in C#, 398—400 Default value, 896, 1368 delegate covariance, 413—415 Default.aspx file, 1446, 1449, 1468, 1469, generic, 415—418 1493, 1505, 1506 method group conversion syntax, 411— Default.aspx page, 1496, 1505 413 DefaultDrawingAttributes property, 1224 sending object state notifications using defaultProvider, 1505 enabling multicasting, 408—409 default(T) syntax, 390 overview, 405—407 defaultValue attribute, 1504 removing targets from delegate's DefaultValue property, DataColumn class, invocation list, 410—411 890 simplest possible delegate example, DefaultView member, 897 402—404 DefineConstructor( ) method, 696 System.MulticastDelegate and DefineDefaultConstructor( ) method, 697 System.Delegate base classes, 400— DefineDynamicModule( ) method, 694 401 DefineEnum( ) method, 694 delegation, programming for, 232—235 DefineLabel( ) method, 690 DELETE command, 914 DefineMethod( ) method, 697 delete keyword, 9, 289 DefineResource( ) method, 694 Delete( ) method DefineType( ) method, 694 DataRow class, 895, 907 defining Directory class, 783 groups, 1463—1465 DirectoryInfo class, 778 user profiles within Web.config, 1504— FileInfo class, 785 1505 FileSystemInfo class, 778 DefiningGeometry property, Shape class, Delete statement, 861, 862, 1450 1248 Delete Sticky Note button, 1234
1619
INDEX ■
DeleteCar( ) method, 875 Design tab, SharpDevelop, 52 DeleteCommand property, 914, 918, 949 designer toolbox, SharpDevelop, 52 Deleted value, 895
1620
INDEX ■
ASP.NET, 1401—1403 overview, 903 role of CIL, 655 selecting rows based on filter directly creating types, 797—798 criteria, 908—911 Directory class, 776, 777 updating rows within DataTable, Directory method, FileInfo class, 785 911 Directory types, 782—783 data adapters DirectoryApp project, 783 mapping database names to friendly Directory.GetFiles( ) method, 764 names, 916 DirectoryInfo class, 776, 777 overview, 913 DirectoryInfo types simple data adapter example, 914— abstract FileSystemInfo base class, 777— 915 778 DataColumn types creating subdirectories with adding objects to DataTable types, DirectoryInfo type, 781—782 892—893 enumerating files with DirectoryInfo building, 891—892 type, 780—781 enabling autoincrementing fields, DirectoryName method, FileInfo class, 785 892 DirectX layer, 1120 overview, 889—890 dirty entities, 990 DataRow type dirty window, 1549 DataRowVersion property, 896—897 DisableAllButton style, 1319 overview, 893 Disassembler window, 36 RowState property, 894—896 disco utility, Mono, 1571 DataSet types disco.exe utility, Microsoft .NET, 1571 building, 889 disconnected functionality, testing, 920— key methods of, 888 921 key properties of, 887 disconnected layer, of ADO.NET overview, 886 adding disconnection functionality to DataTable type AutoLotDAL.dll inserting into DataSets, 898 configuring data adapters using obtaining data in DataSets, 898—899 SqlCommandBuilder class, 918— overview, 897 919 processing data using defining initial class types, 917 DataTableReader objects, 899—901 GetAllInventory( ) method, 919 serializing DataTable/DataSet setting version numbers, 919 objects as XML, 901—902 testing disconnected functionality, serializing DataTable/DataSet 920—921 objects in binary format, 902—903 UpdateInventory( ) method, 919 isolating strongly typed database code binding DataTable objects to Windows into class libraries Forms GUIs deleting data with generated codes, DataView type, 912—913 942—943 deleting rows from DataTable, 907— inserting data with generated codes, 908 941—942 hydrating DataTable from generic invoking stored procedure using List
1621
INDEX ■
overview, 938 UpdateInventory( ) method, 919 selecting data with generated codes, discrete key frames, authoring animation 940—941 in XAML, 1311—1312 viewing generated codes, 939—940 DiscreteStringKeyFrame elements, 1312 multitabled DataSet objects and data Dispatcher class, 1135 relationships Dispatcher property, 1135 building table relationships, 924 DispatcherObject class, 1135 navigating between related tables, Display( ) method, 685 925—927 display name, 598, 599 overview, 921 Display property, 1458, 1462 prepping data adapters, 922—923 DisplayBaseClass
1622
INDEX ■
*.dll file extension, 12—13, 14, 532, 559, 663, DOM (Document Object Model), 993, 995, 1083 1011, 1388, 1389 DLL hell, 6, 577 DOM models vs. XML APIs, 995—996 *.dll module, 14 domain first programming, 962 *.dll .NET binaries, 12 Domain Name Service (DNS), 1380, 1381 [DllImport] attribute, 605 Domain Name System (DNS), 1418 DLR. See dynamic types and Dynamic DomainUnload event Language Runtime AppDomain class, 640 DNS (Domain Name Service), 1380, 1381 AppDomain type, 647 DNS (Domain Name System), 1418 DontUseCorLibDumper.dll, 1578 do keyword, 682 dot (.) prefix, 655 Dock property, 1326, 1526 dot operator, 152, 290, 302, 339, 519, 703 DockPanel class, 1138, 1162, 1326 dotNetFx40_Client_x86_x64.exe runtime DockPanel panels, 1193—1194 profile, 37 DockPanel types, 1194 dotNetFx40_Client_x86.exe setup
1623
INDEX ■
DragDrop event, 1528 DrawPath( ) method, 1548 DragEnter event, 1528 DrawPie( ) method, 1548 DragLeave event, 1528 DrawRectangles( ) method, 1548 DragOver event, 1528 DrawString( ) method, 1548, 1550 Draw( ) method, 242, 243, 244, 245, 246, DrawUpsideDown( ) method, 340 337, 338, 340, 341, 342 dreamCar object, 549 DrawArc( ) method, 1548 DriveInfo class, 776 DrawBeziers( ) method, 1548 DriveInfo class types, 783—784 DrawCurve( ) method, 1548 DriveInfoApp project, 784 DrawEllipse( ) method, 1548 DriveNames variable, 1098, 1099 DrawIcon( ) method, 1548 driverName field, 175 DrawIn3D( ) method, 332 Drop activity here area, 1081 DrawInBoundingBox( ) method, 340 dropdown area, 1217 Drawing class, 1258, 1271 DropDownItems property, 1516 Drawing object, 1258, 1271 Dump menu option, 659 Drawing type, 1272 dumpbin.exe file, 535 DrawingAttributes object, 1224 DumpTypeToFile( ) method, 1572 DrawingBrush duplex messaging, 1030 building using geometries, 1272—1273 Duration object, 1307 painting with, 1273—1274 Duration property, 1306, 1307, 1310 DrawingBrush class, 1258 dynamic assemblies DrawingBrush object, 1272, 1278 emitting DrawingBrush type, 1258 assembly and module set, 693—694 DrawingContext class, 1278, 1279 constructors, 696—697 DrawingContext object, 1278, 1279 HelloClass type and String Member
1624
INDEX ■
limitations of, 706—707 ECMA (European Computer overview, 701—702 Manufacturers Association), 1562 practical uses of, 707 ECMA International web site, 654 role of Microsoft.CSharp.dll ECMA-334 specification, 38, 1562 assembly, 705 ECMA-335 specification, 38, 1562 scope of, 706 Edit Columns dialog, 988 COM interoperability Edit menu, 1196, 1202 simplifying using dynamic data, edit mode, for code snippets, 63 714—718 EditingCommands class, WPF, 1202 using C# 4.0 language features, 718— EditingMode property, 1222 724 EDM. See entity data model without C# 4.0 language features, EdmGen.exe file, 961 722—724 *.edmx file, 958 role of DLR generating, 961—965 dynamic runtime lookup of viewing generated data, 968—970 expression trees, 709—710
1625
INDEX ■
embedding, interop metadata, 716—717 encapsulation Emit( ) method, 690, 691, 696 of classes EmitCall( ) method, 690 internal representation of emitting HTML content, 1422 properties, 202—203 EmitWriteLine( ) method, 690, 697 overview, 194 empAge field, 200 read-only and write-only properties, empBenefits object, 232 204—205 empID field, Employee class, 196 static properties, 205—206 Employee class, 195, 196, 227, 228, 229, using .NET properties, 198—200 230, 232, 234, 235, 237 using properties within class Employee object, 200, 240 definition, 200—201 Employee type, 203, 205, 233 using traditional accessors and EmployeeApp project, 195, 206, 217, 218, mutators, 195—197 226 visibility levels of properties, 204 EmployeeApp.exe assembly, 202 as pillar of OOP, 189 Employee.cs file, 195, 217, 226 End( ) method, 1035, 1069, 1421 Employee.Internal.cs file, 217, 226 EndClose( ) method, 1040 Employees project, 241 EndEdit( ) method, 893 empName field, 196, 197 EndExceptionBlock( ) method, 690 empSSN variable, 203 EndInvoke( ) method, 399, 400, 732, 733, Empty Web Site project, 1473, 1477, 1485, 734, 738, 774, 1086 1489, 1494, 1498, 1504 EndOpen( ) method, 1040 Empty Web Site template, Visual Studio,
1626
INDEX ■
viewing generated *.edmx file data, Entity Set Name field, 967 968—970 Entity Set value, 967 viewing generated source code, 970— Entity SQL, querying with, 977—978 971 Entity Types folder, 965 viewing mappings, 967 EntityCommand class, 957 Entity Framework (EF) EntityConnection class, 957 AutoLotDAL Version 4.0 EntityDataReader class, 957, 961 invoking stored procedure, 985—986 EntityKey object, 974 mapping stored procedure, 980—981 EntityObject class, 956 navigation properties, 982—984, 984— EntityState property, 975 985
1627
INDEX ■
enumeration types, Common Type System incoming, listening to, 422—423 (CTS), 21 overview, 418 enumerations, 21, 144, 145, 147, 671 registrating, simplifying event using Enum.Format( ) method, 148 Visual Studio 2010, 423—424 Enum.GetUnderlyingType( ) method, 147, Events tab, 1171, 1181, 1370 148
1628
INDEX ■
ExitCode property, System.Environment initial C# code, 1359 class, 81 overview, 1356 ExitEventArgs class, 1137 programmatically starting ExitEventHandler delegate, 1137 storyboard, 1363—1364 ExitTime property, System.Diagnostics. renaming initial, 1357—1358 Process class, 628 SpinControl, 1358 exitToolStripMenuItem menu, 1523 working with shapes using Expander control, 1198, 1206 brush and transformation editors, Expander widget, 1195 1269—1271 ExpenseIt WPF sample program, 1124 combining shapes, 1268 explicit attribute, 669 converting shapes to paths, 1267— explicit cast operation, 107, 249, 1107 1268 explicit conversions overview, 1266 for square types, 458 selecting shape to render from tool when required, 454 palette, 1266—1267 explicit interface implementation, 336, Expression property, DataColumn class, 337, 339, 342 890 explicit keyword, 455, 456 expression trees, 708—710 explicit load, 554 extendable applications explicitly implemented interface, 338 C# Snap-In, 619—620 explicitly pop, 679 CommonSnappableTypes.dll, 619 Exploded event, 420, 421, 428 extendable Windows Forms exponential format, 84 application, 621—624 exponential notation, 84 overview, 618 Export All button, 1276 Visual Basic Snap-In, 620 Export button, 720 extendable Windows Forms application, Export dialog box, 1276 621—624 Export menu option, 1276 ExtendedProperties collection, 898 exporting, design document to XAML, ExtendedProperties property, 887 1275—1276 extending interface types, 469—470 ExportToExcel( ) method, 720, 722 extends attribute, 655, 660, 669, 670 exposing single services using multiple extends clause, 670 bindings, 1052—1053 Extends token, 583 Expression area, 1107 Extensible Application Markup Language Expression Blend (XAML), 993 building user interface with Extensible Hypertext Markup Language key aspects of, 1207—1213 (XHTML), 1383, 1392 TabControl control, 1213—1215 Extensible Markup Language (XML), 995, establishing data bindings using, 1236— 996, 997, 998, 999, 1000, 1001, 1238 1002, 1003, 1004 extracting resources in, 1301—1303 Extensible Markup Language (XML) generating WPF styles with, 1320—1324 schema editor, 902 populating FlowDocument, 1230—1231 Extensible Markup Language Path UserControls, building custom Language (XPath), 993 animation, defining, 1359—1362
1629
INDEX ■
Extensible Markup Language Query Factory property, Task class, 766 (XQuery), 993 false branch, 1097 Extensible Markup Language Schema false operator, 445 Definition (XSD) editor, 902 false value, 330 Extensible Stylesheet Language Family FCLs (Framework class libraries), 3 Transformations (XSLT), 993 feed project template, RSS, 1024 extension libraries, 467—468 Field #n token, 583 extension methods field access, with pointers, 484 extending interface types with, 469—470 field data extension libraries, 467—468 defining in CIL, 674—675 importing types that define, 465—466 static, 182—185 IntelliSense mechanism, 466—467 .field directive, 674 invoking on instance level, 463 Field
1630
INDEX ■
File(Info) types, 777—778 finalization queue, 305 FileMode enumeration, 787 finalization reachable table, 305 FileName property, 1559 Finalize( ) method, 252, 298, 302, 303, 305, FileNotFoundException class, 260, 281 306, 310 FileNotFoundException error, 1578 finally blocks, 282, 304, 690 FileNotFoundException exception, 554, finally clause, 756 555, 569 finally keyword, 261 FileNotFoundException object, 281 FindAll( ) method, 430, 431, 432, 491 File.Open( ) method, 281, 1175 FindByCarID( ) method, 934 FilePath property, 1418 FindLongestWord( ) method, 769 files FindLongestWord( )method, 770 enumerating with DirectoryInfo type, FindMembers( ) method, System.Type 780—781 class, 588 watching programmatically, 801—804 Find/Replace dialog box, 1542 FileStream class, 776 FindTenMostCommon( ) method, 769, 770 FileStream object, 788 Finish button, 930, 1456 FileStreamApp project, 793, 794 FinishButtonClick event, 1456 FileStreams class, 793—794 First
1631
INDEX ■
Flowchart activity, 1090, 1093, 1094, 1107 for statement, 117 Flowchart section, Toolbox, 1093 ForAll( ) method, 771 flowchart workflows forcing garbage collection, 299—302 connecting activities in, 1094 ForEachT activity, 1099—1100 defining workflow wide variables, 1095— foreach code, 63 1096 foreach construct, 63, 343, 345, 346, 497, FlowDecision activity, 1096—1097, 1098 500 ForEachT activity, 1099—1100 foreach enumeration, 346, 1100 InvokeMethod activity, 1094—1095 foreach iteration, 906 overview, 1093 foreach keyword, 78, 118, 344, 346, 349, TerminateWorkflow activity, 1097 682, 771, 1099 FlowDecision activity, 1090, 1094, 1096— foreach logic, 502 1097, 1098 foreach loop, 118, 245, 346, 590, 594, 985 FlowDocument foreach scope, 623 loading, 1234—1235 foreach style, 362 populating, 1230—1232 foreach syntax, 346 saving, 1234—1235 ForEach
1632
INDEX ■
Form1.cs icon, 1520 freachable table, 305 Format drop-down list, 1276 friend assemblies, 545 Format( ) method, String system type, 97 friendly names, mapping database names FormatException class, 260 to, 916 FormatNumericalData( ) method, 84 FriendlyName property, 639 FormattedResponse argument, 1105, 1107 from operator, 497, 510, 517, 518 FormattedResponse variable, 1108, 1111 From property, 1305, 1307, 1310 FormattedText object, 1279 FromHdc( ) method, 1548 formatters, for serialization FromHwnd( ) method, 1548 IFormatter and IRemotingFormatter FromImage( ) method, 1548 interfaces, 809—810 FTP (File Transfer Protocol), 1381, 1407 overview, 808 Full Installation option, Mono website, type fidelity among formatters, 810—811 1566 formatting, 84 FullName property, FileSystemInfo class, FormBorderStyle enumeration, 1529 778 FormBorderStyle property, 1529, 1538 fully qualified name, 31, 252, 532 FormBorderStyle.FixedDialog property, Func<> delegates, 492, 517, 518, 519, 520 1538 Func<> type, 521 FormClosed event, 989, 1531, 1532 Func
1633
INDEX ■
Garage class, 209, 343, 346, 347 creating custom generic structures and Garage object, 210 classes, 388—392 garbage collection defining in CIL, 671—672 background (.NET 4.0), 297 generic type parameters, 371—375 concurrent (.NET 1.0 - 3.5), 297 non-generic collections, issues with forcing, 299—302 overview, 361—362 GC.Collect( ) method, 298, 299, 300, 301, performance, 363—367 302 type safety, 367—371 GCCollectionMode enumeration, 298, 300 System.Collections.Generic namespace *.g.cs file, 1150, 1165 collection initialization syntax, 378 GC.SuppressFinalize( ) method, 310 List
1634
INDEX ■
GetAllInventoryAsList( ) method, 874 GetID( ) method, 197 GetAllTracks( ) method, 314, 315 GetILGenerator( ) method, 696 GetArea( ) method, 1254 GetInterfaces( ) method, 588, 591 GetAssemblies( ) method, 638, 641 GetIntFromDatabase( ) method, 163, 164 GetBenefitCost( ) method, 232 GetInventory( ) method, 1072 GetBoolFromDatabase( ) method, 163 GetInvocationList( ) method, 402 GetChanges( ) method, 888 GetLogicalDrives( ) method, 782, 1098 GetChildren( ) method, 1342 GetMembers( ) method, System.Type GetCoffee( ) method, 382, 383 class, 588 GetColumnError( ) method, 893 GetMethods( ) method, System.Type class, GetColumnsInError( ) method, 893 588 GetCommandLineArgs( ) method, 78, 79 GetMsg( ) method, 691 GetConstructors method ( ), System.Type GetName( ) method, 197 class, 588 GetNestedTypes( ) method, System.Type GetCurrentPay( ) method, 197 class, 588 GetCurrentProcess( ) method, GetNumberOfPoints( ) method, 324 System.Diagnostics.Process class, GetObjectByKey( ) method, 959, 974, 975 629 GetObjectData( ) method, 820, 822 GetCurrentThreadId( ) method, GetParameters( ) method, 594 AppDomain class, 639 GetPerson( ) method, 368 GetDirectories( ) method, DirectoryInfo GetPetName( ) method, 67, 843 class, 778 GetPetName procedure, 869, 943 GetDomain( ) method, GetPosition( ) method, 1143 System.Threading.Thread Class, GetProcesses( ) method, 741 System.Diagnostics.Process class, GetDomainID( ) method, 629 System.Threading.Thread Class, GetProperties( ) method, System.Type 741 class, 588 GetDrives( ) method, DriveInfo class, 783 GetRandomNumber( ) method, 181, 182 GetEnumerator( ) method, 343, 344, 345, GetRenderBounds( ) method, 1254 346, 348, 349 GetSchema( ) method, 855
1635
INDEX ■
GetVisualChild( ) method, 1281 graphical transformation objects, 1264 GiveBonus( ) method, 235, 236, 237, 239, Graphical User Interface (GUI), 38, 81, 903, 240 904, 1006, 1007, 1059, 1060, 1061, GivePromotion( ) method, 249, 250 1389 Glade 3 tool, Mono, 1571, 1572 Graphical User Interface Toolkit (GTK#), Global Application Class icon, 1479 1565, 1566 global application object, 1140 graphics Global Assembly Cache, 848 retained-mode, 1245 Global Assembly Cache (GAC), 32, 51, 533, vector, 1120 559, 560, 561, 565—566, 1022, 1414 Graphics class, 1549 global last-chance exception event Graphics object, obtaining with Paint handler, 1481—1482 event, 1549—1550 Global.asax file Graphics type, 1548—1549 global last-chance exception event GreaterThan value, 1461 handler, 1481—1482 *.g.resources file, 1151 HttpApplication base class, 1482 Grid class, 1138, 1160, 1162 overview, 1479—1480 Grid control, 1349 Global.asax script, 1482 Grid panels, 1186, 1191—1193 Global.asax.cs, 1485
1636
INDEX ■
GrowLabelFont.xaml file, 1309 HeaderText property, 1462 Grunt value, 147 heap allocation, 291, 366 GTK# (Graphical User Interface Toolkit), Height attribute, 1146 1565, 1566 Height property, 1133, 1145, 1152, 1187, GUI (cache application Graphical User 1193, 1304, 1305, 1326, 1327, 1438 Interface), 1492 Height value, 1188, 1189, 1193 GUI (Graphical User Interface), 38, 81, 903, HeightProperty field, 1329 904, 1006, 1007, 1059, 1060, 1061, Helicopter class, 550 1389 helicopter.cs file, 550, 551 GUI (session application Graphical User Hello World application, 27 Interface), 1495 -HelloClass constructor, 696 GUI animation tools, 1304 HelloClass type, emitting, 695—696 GUI editor, 543 HelloMsg.cs file, 46 GUI framework, 618 HelloProgram.cs file, 658 GUID (globally unique identifier), 351, 560, HelloProgram.exe file, 659 889, 899 HelloProgram.il file, 664 GZIP standard, 1394 HelloWebService.asmx file, 1017 HelloWorld class, 691, 695, 697 HelloWorld( ) method, 1018 ■H helloWorldClass variable, 697 HelloWorldWebService project, 1019 H command, 1257 Help cursor, 1314
tag, 1386 Help Library Manager, 68 Halo8.exe application, WPF, 43 Help menu, SharpDevelop, 53 Handle property, System. Diagnostics. Help page, 68 Process class, 628 Helper class, rigging up UI to, 1009—1011 Handled property, 1339, 1341, 1537 HelpExecuted( ) method, 1204 [HandledProcessCorruptedStateException HelpLink property, 262, 268, 269—270 s] attribute, 286 [helpstring] attribute, 658 hard-code, 1236 hexadecimal formatting, 84 has-a relationship, 5, 190, 213, 219, 232, Hexagon class, 189, 191, 324, 525 806 Hexagon object, 333 HasChanges( ) method, 888 Hexagon type, 243, 328, 329 HasControls( ) method, 1432 hidden this reference, 682 HasErrors property, 888, 893 Hide( ) method, 1529 hash code, 255, 256, 560, 561 hit test operations, responding to, 1282— HashSet class, 377 1284 Hashtable class, 362, 1479 HitTest( ) method, 1283 Hashtable types, 251, 255 HitTestResult object, 1252 HasValue property, 163, 164 HitTestResultCallback delegate, 1283 HatchBrush object, 1550 Home node, 1446 header information, Windows, 534 Horizontal split button, 1170 Header property, 1214 Horizontal value, 1190 Header values, 1196 HorizontalAlignment property, Headers property, 1418 FrameworkElement type, 1133 1637
INDEX ■
HorizontalContentAlignment property, HttpApplicationState object, 1484, 1485, Control Type, 1133 1488 HorseAndBuggy class, 607 HttpApplicationState type, 1482, 1483, HorseAndBuggy type, 607 1484, 1486, 1487, 1488, 1489 element, 1039, 1043 HTTP-based bindings, 1029—1030 hosting HttpBrowserCapabilities class, 1419 services within Windows services HttpBrowserCapabilities object, 1419 creating Windows service installer, HttpCookie class, 1498 1064—1065 HttpCookie collection, 1421 enabling MEX, 1064 HttpCookie type, 1497, 1498 installing Windows service, 1066— HttpCookie.Expires property, 1498 1067 HttpMethod property, 1418 overview, 1061 HttpRequest class, 1417, 1418, 1419, 1420 specifying ABCs in code, 1062—1063 HttpRequest object, 1482 Windows Communication Foundation HttpRequest.Browser property, 1389 (WCF) services HttpRequest.Cookies property, 1498, 1499 element, HttpRequest.Form form, 1436 1042 HttpRequest.Form property, 1419 coding against ServiceHost type, HttpRequest.QueryString property, 1419 1038 HttpResponse class, 1419, 1421, 1422 enabling metadata exchange, 1043— HttpResponse object, 1482 1045 HttpResponse.Redirect( ) method, 1422 establishing ABCs within App.config HttpResponse.Write( ) method, 1422 files, 1037 HttpResponse.WriteFile( ) method, 1422 overview, 1036 HttpServerUtility object, 1417, 1482 ServiceHost type, 1040—1041 HttpServerUtility.ClearError( ) method, specifying base addresses, 1038— 1426 1040 HttpServerUtility.GetLastError( ) method, href property, 577 1426 HRESULTs, 260 HttpServerUtility.Transfer( ) method, 1422 HTML. See HyperText Markup Language HttpSessionState class, 1483, 1496—1497 HTML attributes, 1441 HttpSessionState object, 1482, 1483, 1493, HTML controls, 1441 1496, 1502 HTML tab, Visual Studio, 1384 HttpSessionState type, 1483, 1494 HTML widget, 1440 HyperLink widget, 1433 tag, 1383 HyperText Markup Language (HTML) HtmlButton tag, 1440 building forms, 1386—1387 HtmlInputControl tag, 1440 document structure, 1383—1384 HtmlTable tag, 1440 forms, 1384, 1477 HTTP. See Hypertext Transfer Protocol overview, 1382 HTTP GET method, 1043 representation, 1477 HttpApplication class, 1481, 1482, 1488 requests, 1482 HttpApplication type, 1473, 1483 response, 1477, 1482 HttpApplicationState class, 1484 Visual Studio 2010 designer tools, 1384— 1386
1638
INDEX ■
widgets, 1476 Icon type, 1547 Hypertext Transfer Protocol (HTTP) IContextProperty interface, 651 overview, 1379 ICreateErrorInfo interface, 261 request/response cycle, 1380 ICustomFormatter interface, 85 requests, incoming, 1417—1420 ID attribute, 1397 response, outgoing, 1421—1423 Id member, ProcessThread type, 633 stateless protocols, 1380 ID property, 198, 200, 628, 1429, 1432 IDataAdapter interface, 828, 835 IDataAdapter type, System.Data ■I namespace, 832 IDataParameter interface, 828, 834—835 I command, 872 IDataParameter type, System.Data -i command, 566 namespace, 832 i parameter, 433 IDataReader interface, 827, 836 i variable, 682, 683 IDataReader type, System.Data tag, 1386 namespace, 832 IAdvancedDraw interface, 340 IDataReader.IsDBNull( ) method, 837 IAppFunctionality interface, 619, 620, 622 IDataRecord interface, 827, 836 IAsyncResult compatible object, 733 IDbCommand interface, 827, 834 IAsyncResult interface, 399, 734, 735, 774 IDbCommand type, System.Data IAsyncResult parameter, 732, 736, 738, 739 namespace, 832 IAsyncResult-compatible object, 732 IDbConnection interface, 321, 327, 827, IAsyncResult-compatible parameter type, 833 732 IDbConnection parameter, 837 IAutoLotService.cs file, 1072 IDbDataAdapter interface, 828 IBasicMath class, 1054 IDbDataAdapter type, System.Data IBasicMath interface, 469 namespace, 833 IBasicMath.cs file, 1057 IDbDataAdapterinterface, 835 IClassFactory interface, 7 IDbDataParameter interface, 828, 834—835 ICloneable class, 323 IDbTransaction interface, 828, 834, 878, ICloneable interface, 158, 323, 349—354, 879 362 IDbTransaction type, System.Data ICloneableExample application, 323 namespace, 833 ICloneableExample project, 324 IDE (integrated development ICollection interface, 362, 377, 378 environment), 932, 996, 1024, ICollection interface, 376, 377, 378 1025, 1379, 1381, 1382, 1386, 1396, ICommand interface, 1201, 1205 1410 IComparable interface IdealProcessor member, ProcessThread building, 354—359 type, 633 overloading comparison operators, 450 IDictionary interface, 262, 270, 362 IComparable interface, 354 IDictionary interface, 1113 IComparer interface, 143, 357—358 IDictionary interface, 376 IComparer interface, 358, 376, 383 IDispatch interface, 7, 709 IComponent interface, 1525 IDisposable class, 863, 1550 IComponentConnector interface, 1151
1639
INDEX ■
IDisposable interface, 289, 305, 306, 307, IL (Intermediate Language), 12, 13 308, 309 *.il file, modifying, 662—663 IDraw3D interface, 331, 332, 333 ilasm compiler, Mono, 1569 IDrawable interface, 339, 341, 393 ilasm utility, Mono, 1571 IDropTarget interface, 322 ilasm.exe compiler, 666 IDynamicObject interface, 709 ildasm.exe file IEightBall interface, 1033, 1046 compiling CIL code using, 663—664 IEnumerable interface, building exploring assemblies using building iterator methods with yield overview, 33 keyword, 346 viewing assembly metadata, 35 building named iterator, 347—348 viewing Common Intermediate internal representation of iterator Language (CIL) code, 34 method, 348—349 viewing type metadata, 34 overview, 343—345 ILGenerator class, 691, 696, 697 IEnumerable type, 504 ILGenerator member, 689 IEnumerable interface, 499 ILGenerator objects, 690 IEnumerable, 498, 505 ILGenerator type, 690, 696 IEnumerable class, 497, 504, 505, 506, IList interface, 362 507, 945, 948 IList interface, 376 IEnumerable enumeration, 961 Image control, 1274, 1275, 1278, 1279, IEnumerable interface, 376, 377, 500, 1286, 1289, 1358, 1359 763, 765, 1000 Image property, 1544 IEnumerable object, 507 Image type, 1547 IEnumerable variable, 499 ImageAnimator type, 1547 IEnumerator interface, building ImageBrush type, 1258 building iterator methods with yield ImageDrawing class, 1246 keyword, 346 ImageDrawing object, 1258 building named iterator, 347—348 ImageDrawing type, 1271 internal representation of iterator ImageOrderAutoDialog class, 1545 method, 348—349 ImageOrderAutoDialog.cs file, 1543 overview, 343—345 images IEnumerator interface, 376 2D vector, 1271 IErrorInfo interface, 261 programmatically loading, 1288—1289 If activity, 1089, 1107—1108, 1110 ImageSource object, 1258 if keyword, 122 ImageSource property, 1258 if scope, 250 ImageUrl image, 1448 if statement, 120, 1317 IMetadataExchange class, 1055 if/else branches, 1104 imgDisplay control, 1358 if/else statement, 119, 120 imgFirst object, 1371 if/else/then statement, 1107 imgSecond object, 1371 IFormatter interface, 809—810 imgThird object, 1371 IIS (Internet Information Services), 1025, immediate-mode graphical systems, 1245 1026, 1036, 1037, 1040, 1071, 1074, immutability, 103 1379, 1381, 1382 implemented interfaces, custom metadata IIS virtual directories, 1381 viewer, 591
1640
INDEX ■
implements attribute, 655, 669, 670 index operator ([]), accessing items from implements clause, 670 arrays, 439 Implements keyword, 620 indexer methods implicit cast, 248 definitions on interface types, 444 implicit conversion function of, 439 routines, 458—459 multiple dimensions, 443—444 when required, 454 overloading, 443 implicit keyword, 455, 456, 459 overview, 439—440 implicit load, 554 string values, 441—442 implicit typing, 113, 701, 702 IndexOutOfRangeException class, 260 implicitly pop, 680 IndexOutOfRangeException type, 262 implicitly sealed, 223 infrastructure, adding to MainWindow implicitly typed local arrays, 139 type, 1555 implicitly typed local variables inheritance. See also polymorphism are strongly typed data, 115 base class/derived class casting rules overview, 112—113 is keyword, 250 restrictions on, 114—115 as keyword, 249 usefulness of, 116 overview, 247—248 ImplicitlyTypedLocalVars project, 112, 117 basic mechanics of <%@Import%> directives, 1398, 1402, 1403 multiple base classes, 222 elements, 1149 overview, 219 importing sealed keyword, 222—223 Inventory.xml files, 1007—1008 specifying parent class of existing types that define, 465—466 class, 220—221 Imports area, 1105 cross-language, 549 Imports button, 1105 details of Imports editor, 1105 adding sealed class, 231—232 Imports keyword, 548 controlling base class creation with Imports statement, 548 base keyword, 228—230 in operator, 497, 509, 510, 517, 518 overview, 226—227 In32Animation class, 1304 protected keyword, 230 InArgument<> properties, 1109 multiple, with interface types, 341—342 InArgument class, 1109 overview, 219 InArgument object., 1109 pillar of OOP, 189—191 inaryFormatter class, 529 programming for Include attribute, 1149 containment/delegation, 232—235 incoming cookie data, reading, 1499 revising Visual Studio class diagrams, incoming HTTP requests 224—225 access to incoming form data, 1419— System.Object class 1420 overriding system.Object.Equals( ), IsPostBack property, 1420 254—255 obtaining brower statistics, 1419 overriding overview, 1417—1418 System.Object.GetHashCode( ), incoming parameter, 146 255—256 Increment( ) method, 756, 757
1641
INDEX ■
overriding system.Object.ToString( in-memory representation, 9 ), 254 inner exceptions, 281 overview, 250—253 innerEllipse object, 1339 testing modified person class, 257— InnerException property, 263, 281 258 in/out parameter, 871 testing your modified person class, in-place editing, enabling, 1454 256 input button, setting default, 1541 inheritance chain, 615, 1416 input parameter, 78, 871 Inheritance icon, Class Designer Toolbox, input/output (I/O), 8 66 INSERT command, 914 Inheritance Picker dialog box, 1544 Insert( ) method, 97, 365, 380, 441, 1489, Inherited Form icon, 1543 1490 Inherited property, 612 Insert request, 861 Inherits attribute, 1402, 1409 Insert Snippet option, 63 Inherits keyword, 549 Insert Standard Items option, 1522 init attribute, 681 Insert statement, 862, 863, 955, 974, 1450 Init event, 1423, 1476 InsertAuto( ) method, 863, 864, 865, 868, InitClass( ) method, 934 875, 876, 1074 InitDAD( ) method, Program class, 643 InsertCar( ) method, 1072, 1073 Initial Catalog name, 854 InsertCommand property, 914, 918, 949 initial class types, 917 Insert/Delete logic, 882 InitializeComponent( ) method, 1151, InsertNewCar( ) method, 875—876 1153, 1165, 1203, 1520, 1521, 1523, InsertNewElement( ) method, 1008 1524 installing InitializeCorrelation activity, WF 4.0, 1090 Mono, 1565—1568 InitialValue property, 1459 strongly named assemblies to GAC, Ink API controls, 1183 565—566 Ink API support types, 1183 Windows service, 1066—1067 Ink API tab, WPF InstallSqlState.sql file, 1502 ComboBox control, 1224—1226 installutil MathWindowsServiceHost.exe InkCanvas control, 1222—1227 command, 1066 overview, 1216 instance attribute, 675 RadioButton control, 1220—1222 instance data, 182 ToolBar, 1217—1219 instance level, invoking extension ink controls, WPF, 1182—1183 methods on, 463 Ink mode, 1223 int data type, 86, 87, 92, 96, 106, 107, 108, Ink Mode! value, 1218 112, 116, 145 InkCanvas control, WPF, 1222—1227 int parameters, 106 InkCanvasEditingMode enumeration, 1223 int type, 356 inkRadio control, 1219 int variable, 107, 363, 364, 1289 inkToolbar control, 1217 intArray declaration, 138 inkToolbar node, 1217 IntCollection class, 369 inline elements, WPF, 1227 integer (0), 1335 inline menu editor, 1522, 1523 Integer data type, 135, 1479 in-memory data allocation, 183, 184
1642
INDEX ■
integrated development environment interface types vs. abstract base (IDE), 932, 996, 1024, 1025, 1379, classes, 322—325 1381, 1382, 1386, 1396, 1410 overview, 321 IntelliSense, 136, 466—467, 704 Interlocked class, 740, 756, 757 IntelliSense window, 423 Interlocked.CompareExchange( ) method, interactive graphical data, 1246 757 interface attribute, 670 Interlocked.Exchange( ) method, 757 interface implementation, 336, 337, 339, Interlocked.Increment( ) method, 757 342 Intermediate Language (IL), 12, 13 interface keyword, 20, 325 Intermediate Language Disassembler Interface member, 695 utility, 33 interface types internal data, of objects, 194 Common Type System (CTS), 20 internal keyword, 20, 125, 193, 194, 545 definitions on, 444 internal modifier, 193, 194 extending, 469—470 internal reference counter, 292 InterfaceExtensions project, 469, 470 internal representation InterfaceHierarchy application, 339 of anonymous types, 474—475 InterfaceHierarchy project, 340 of overloaded operators, 451—452 InterfaceNameClash application, 336 InternalsVisibleToAttribute class, 545 InterfaceNameClash project, 339 International Organization for interfaces Standardization (ISO), 1562 building cloneable objects, 349—354 Internet Information Services (IIS), 1025, building comparable objects, 354—359 1026, 1036, 1037, 1040, 1071, 1074, building enumerable types 1379, 1381, 1382 building iterator methods with yield Internet Protocol (IP) address, 1380, 1381, keyword, 346 1418 building named iterator, 347—348 interop assemblies, 10, 714, 717 internal representation of an interop library, 716 iterator method, 348—349 interoperability assemblies, 714, 716 overview, 343—345 interoperability data, 716 custom, defining, 325—327 interoperating, 1121 defining and implementing in CIL, 670 Interrupt( ) method, 742 designing hierarchies, 339—342 Intersect( ) method, 515 explicit implementation of, resolving Intersect<>( ) method, 509 name clashes via, 336—339 into operator, 509 generic, specifying type parameters for, intrinsic control command objects, WPF, 374—375 1201 implementing, 327—328 intVal variable, 757 invoking interface members at object Invalidate( ) method, 1246, 1529, 1551, level, 329—331 1556, 1557 as parameters, 331—333 invalidating form's client area, 1551 as return values, 333 InvalidCastException exception, 329, 365 types InvalidOperationException errors, 636 arrays of, 334 Inventories property, 959 Inventory database, 973
1643
INDEX ■
Inventory objects, 984, 989, 1242 invoking services asynchronously from Inventory property, 932, 934 clients, 1067—1069 Inventory schema, 954 invoking statically, 464 Inventory table, 840—842, 850, 853, 860, I/O (input/output), 8 861, 862, 863, 864, 865 I/O and object serialization Inventory table icon, 842 abstract stream class, 792—794 Inventory variable, 1107 BinaryWriters and BinaryReaders Inventory.aspx file, 1446, 1450 classes, 799—801 Inventory.aspx page, 1454 configuring objects for serialization InventoryDAL class, 862, 863, 864, 865, overview, 806 874, 875, 880—882 public fields, private fields, and InventoryDAL object, 863, 872 public properties, 807—808 InventoryDAL type, 867, 870, 875, 1492 serializable types, 807 InventoryDALDisconnectedGUI customizing Soap/Binary serialization application, 920 processes InventoryDALDisconnectedGUI project, overview, 818—819 921 using attributes, 823 InventoryDALDisLayer class, 917, 920, using ISerializable interface, 820— 1106 822 InventoryDALDisLayer object, 918, 921 Directory type, 782—783 InventoryDALDisLayer variable, 1106, Directory(Info) and File(Info) types, 1107 777—778 InventoryDataSet class, 932, 933, 936 DirectoryInfo type InventoryDataSet.Designer.cs file, 933 creating subdirectories with, 781— InventoryDataSet.xsd file, 933 782 InventoryDataTable class, 934, 936, 941 enumerating files with, 780—781 InventoryDataTable variable, 934 overview, 778—779 InventoryEDMConsoleApp application, DriveInfo class type, 783—784 961 file type, 789—791 InventoryEDMConsoleApp example, 979 FileInfo class InventoryEDM.Designer.cs file, 970 AppendText( ) method, 789 InventoryEDM.edmx file, 962, 968 Create( ) method, 786 InventoryEDM.edmx node, 970 CreateText( ) method, 789 InventoryRecord class, 1072, 1074 Open( ) method, 786—788 InventoryRow class, 934 OpenRead( ) method, 788 InventoryTableAdapter class, 936, 937, 940 OpenText( ) method, 789 Inventory.xlsx file, 721, 1007—1008 OpenWrite( ) method, 788 invisible brushes, 1249 overview, 785 Invoke( ) method, 398, 399, 400, 403, 602, files, watching programmatically, 801— 711, 730, 1084, 1086 804 InvokeMember( ) method, System.Type object serialization, 804—806 class, 588 overview, 775 InvokeMethod activity, 1091, 1094—1095, serialization formatters 1096, 1098, 1099 IFormatter and IRemotingFormatter invoking extension methods, 463—464 interfaces, 809—810
1644
INDEX ■
overview, 808 IService1.cs file, 1057 type fidelity among formatters, 810— IService.cs file, 1072 811 ISet interface, 376 serializing collections of objects, 816— IsEvenNumber( ) method, 431 817 isFlipped variable, 1265 serializing objects using IsFocused property, UIElement type, 1134 BinaryFormatter type, 811—813 IsGenericParameter property, serializing objects using SoapFormatter System.Type class, 588 type, 813 IsGenericTypeDefinition property, serializing objects using XmlSerializer System.Type class, 588 type, 814—816 IShape interface, 341 StreamWriters and StreamReaders IsInitiating property, 1035 classes IsInterface property, System.Type class, directly creating types, 797—798 588 overview, 794 IsMDIChildIsMDIContainer property, reading from text files, 796—797 1529 writing to text files, 795—796 IsMouseDirectlyOver property, UIElement StringWriters and StringReaders type, 1134 classes, 798—799 IsMouseOver property, 1134, 1318 System.IO namespace, 775—776 IsNestedPrivate property, System.Type IO namespace, 530 class, 588 IP (Internet Protocol) address, 1380, 1381, IsNestedPublic property, System.Type 1418 class, 588 IPointy interface, 325, 326, 327, 328, 329, IsNull( ) method, 893 330, 333, 334, 335 IsNullable property, 868 IPrintable interface, 341 ISO (International Organization for IRemotingFormatter interface, 809—810 Standardization), 1562 IronPython language, 708 IsolationLevel enumeration, 879 IronRuby language, 708 IsolationLevel property, 879 is keyword, 250, 272, 307, 330—331 IsOneWay property, 1035 is-a relationships, 189, 190, 219, 220, 228, IsPetNameNull( ) method, 935 248, 806 IsPostBack property, 1417, 1420 IsAbstract property, System.Type class, IsPrimitive property, System.Type class, 588 588 IsAlive property, 741 IsSealed property, System.Type class, 588 IsArray property, System.Type class, 588 IsSecureConnection property, 1418 IsBackground property, 741, 750 IssuesWithNon-genericCollections IsChecked property, 1220 project, 371 IsCOMObject property, System.Type class, IsTabStop property, Control Type, 1133 588 IsTerminating property, 1035 IsCompleted property, 734, 735 ISupportErrorInfo interface, 261 IsCreditRisk column, 880 IsValueType property, System.Type class, IsEnabled property, UIElement type, 1134 588 IsEnum property, System.Type class, 588 IsVisible property, UIElement type, 1134 ISerializable interface, 262, 818, 820—822 ItemArray property, 893
1645
INDEX ■
element, 1149 JavaScript language, 1389 ItemHeight value, 1189 JIT (just-in-time) compiler, 536 Items (Collection) dialog box, 1218 JIT compiler, 17, 544, 656 Items (Collection) property, 1217, 1219 Jitter, 17 Items property, 1455, 1477, 1516 Join( ) method, 742 ItemsSource collection, 1242 JpegBitmapEncoder class, 1280 ItemsSource property, 1164 *.jpg files, 763, 764 ItemWidth value, 1189 just-in-time (JIT) compiler, 536 iteration constructs JVM (Java Virtual Machine), 25 do/while loop, 119 -k flag, 561 foreach loop, use of var within, 118 for loop, 117 representing in CIL, 682—683 ■K while loop, 119 IterationsAndDecisions project, 117, 122 kaxaml editor, 1155, 1256, 1263, 1276, 1309 iterator methods kaxaml.exe file, 1154—1156, 1173, 1186, building with yield keyword, 346 1187, 1341 internal representation of, 348—349 key frame animations, 1304 iterators, 346 Key property, DictionaryEntry type, 271 IUnknown interface, 7 keyboard activity, 1534—1537 IValueConverter interface, data conversion keyboard events, intercepting, 1143—1144 using, 1240—1241 KeyCode property, 1537 KeyDown event, 1143, 1144, 1528, 1536, 1537 KeyEventArgs class, 1143, 1517, 1536, 1537 ■J KeyEventArgs type, 1537 Jackpot Deluxe WPF application KeyEventHandler delegate, 1536 .NET 4.0 visual states keyframes, 1360 changing using VisualStateManager KeyNotFoundException exception, 377 class, 1370 KeyPress event, 1528 overview, 1366 keys, determining which was pressed, for StarButton control, 1367—1368 1536—1537 state transition timings, 1368—1369 KeyUp event, 1134, 1143, 1528, 1536 viewing generated XAML, 1369—1370 keyword color coding, 49 extracting UserControl from drawing keywords geometry, 1365—1366 pinning types with, 485—486 finalizing, 1371—1375 XAML, 1156—1159 overview, 1364 Kill( ) method, System.Diagnostics.Process Jackpot.jpg file, 1358 class, 629, 635 jagged arrays, 141 King, Jason, 1561 JaggedMultidimensionalArray( ) method, Knife class, 334 141 Java, programming language comparison, 5 ■L Java Virtual Machine (JVM), 25 L command, 566, 872, 876
1646
INDEX ■
L suffix, 87 invoking methods with parameters, Label class, 912, 920, 925, 1241, 1396, 1397, 603—604 1399, 1403, 1404, 1408 overview, 600 Label control, 1227, 1240, 1331, 1354, 1434, System.Activator class, 601—602 1436, 1439, 1455, 1485, 1495 LateBindingApp application, 601 Label object, 1236, 1309 LateBindingWithDynamic application, 711 Label type, 1304, 1456, 1506 LateBindingWithDynamic project, 711, Label widget, 322, 1422, 1433, 1474 712
1647
INDEX ■
.NET code, 581 LineGeometry object, 1255 COM type, 581 lines consuming workflow, 1112—1114 adding to canvas, 1249—1252 of extension, 467—468 removing from canvas, 1252—1253 external code, 1083 LinkedList class, 377 isolating workflows into dedicated LinkedListNode type, 377 arguments, defining, 1105—1106 LINQ assemblies, importing, 1105 programming to DataSet types with Assign activity, 1107 DataSet extensions library, 945—946 Code activity, 1109—1111 obtaining LINQ-compatible defining project, 1103—1104 datatables, 946—947 If activity, 1107—1108 overview, 943—944 namespaces, importing, 1105 populating new DataTables from Switch activity, 1107—1108 LINQ queries, 948—950 variables, defining, 1106—1107 role of unloading, 639 DataRowExtensions.Field( ) LibraryBuild.rsp file, 1573, 1574 Extension method, 948 life cycle queries, populating new DataTables of ASP.NET Web pages from, 948—950 AutoEventWireup attribute, 1424— LINQ to DataSet term, 494 1425 LINQ to Entities, querying with, 975—977, Error event, 1425—1426 984—985 overview, 1423 LINQ to Objects of Form type, 1531—1533 applying LINQ queries to collection lifeTimeInfo string, 1532 objects lifeTimeInfo variable, 1532 accessing contained subobjects, LIFO (last-in, first-out), 362, 377 506—507 Lightning Bolt button, 1221, 1523 applying LINQ queries to lightweight class type, 151 nongeneric collections, 507—508 lightweight events, 473 filtering data using OfType( ), Limes.jpg file, 1358 508 Line class, 1247, 1256 overview, 505 line geometry, 1261 applying LINQ queries to primitive Line object, 1250, 1252 arrays Line type, 1254 extension methods, 500 element, 1267 implicitly typed local variables, 498— linear gradient, 1258 500 linear interpolation animations, 1304 overview, 496—497 LinearGradientBrush class, 1161 result set, 498 LinearGradientBrush object, 1550 role of deferred execution, 501—502 LinearGradientBrush type, 1161, 1258 role of immediate execution, 502— LineBreak class, 1230 503 LineBreak element, 1227 applying to collection objects, 508 LineBreak type, 1227 C# LINQ query operators LineGeometry class, 1255 aggregation operations, 516—517
1648
INDEX ■
basic selection syntax, 510—511 vs. DOM models, 995—996 LINQ as better Venn diagramming overview, 993—994 tool, 515—516 Visual Basic (VB) literal syntax, 996— obtaining counts using enumerable, 997 513 XML documents obtaining subsets of data, 511 building UI of LINQ to XML App, overview, 508—509 1007 projecting new data types, 512—513 defining LINQ to XML Helper class, removing duplicates, 516 1008—1009 reversing result sets, 514 importing Inventory.xml files, 1007— sorting expressions, 514 1008 internal representation of LINQ query overview, 1006 statements rigging up UI to Helper class, 1009— building query expressions using 1011 enumerable type and anonymous LINQ-compatible datatables, obtaining, methods, 520 946—947 building query expressions using LinqOverArray application, 496 enumerable type and lambda LinqOverArray project, 503 expressions, 519—520 LinqOverArrayUsingEnumerable project, building query expressions using 522 enumerable type and raw LinqOverCollections project, 505, 508 delegates, 521—522 LinqOverDataSet example, 949 building query expressions with LinqOverDataTable( ) method, 945 query operators, 518 LinqRetValues application, 504 overview, 517 LinqRetValues project, 505 LINQ specific programming constructs LinqToDataSetApp application, 946 anonymous types, 493 LinqToXmlFirstLook application, 993 extension methods, 492—493 LinqToXmlObjectModel class, 1008 implicit typing of local variables, 490 LinqToXmlWinApp application, 1007 lambda expressions, 491—492 LinqUsingEnumerable application, 518 object and collection initialization Linux operating system, executing syntax, 491 Windows Forms application overview, 489 under, 1580 returning result of LINQ query, 503—505 List block, 1231 role of LINQ, 493—495 List class, 1230 LINQ to XML List element, 1227, 1231 System.Xml.Linq namespaces, 997— List type, 1227 1002 List<> class, 370 XElement and XDocument objects List<> object, 371, 372 generating documents from arrays List collection, 906 and containers, 1004—1005 List parameter, 506 loading and parsing XML content, List object, 866 1006 List class, 371, 373, 374, 377, 379—380, overview, 1002—1003 491, 719, 763, 1074 XML APIs List container, 1004
1649
INDEX ■
List object, 952 localized assemblies, 598 List type, 373, 493, 505 LocalNullableVariables( ) method, 163 List variable, 374, 506, 671, 905, 1556, .locals directive, 657, 681 1557, 1559 LocalVarDeclarations( ) method, 89 ListBox class, 1164 Location property, 1535 ListBox control, 1224, 1225, 1319, 1431, lock keyword, synchronization using, 753— 1439, 1455, 1477, 1478 754 ListBox type, 621 Lock( ) method, HttpApplicationState ListBox web control, 1477 type, 1484, 1487 ListBoxes control, 1531 lock scope, 754 listCars variable, 905 lock statement, 757 ListControl type, 1431 lock token, 753 ListDictionary type, 363 locks, threading primitives, 729 ListFields( ) method, 591 logging support, 1078 ListInterfaces( ) method, 591 logical model, 958 ListInventory( ) method, 874 logical operators, C#, 120, 121 ListInventoryViaList( ) method, 874 logical resources, 1285 ListMethods( ) method, 590, 594, 595 logical trees, WPF, 1341—1348 listOfHandlers delegate, 406 logical view, 1341 listOfHandlers variable, 407, 418 LogicalTreeHelper class, 1342 lists Login controls, 1440 comma-delimited, 130 lollipop notation, 328 semicolon-delimited, 46 long data type, 87 literal attribute, 674 longhand notation, 718 literal floating point data, 96 longhand reflection calls, 711 Load event, 719, 989, 1409, 1420, 1423, lookless, 1341 1424, 1478, 1492, 1496, 1506 LookUpColorsForMake( ) method, 1009 Load( ) method, 554, 596, 639, 1006 LookUpPetName( ) method, 876 loaded assemblies, 641—643 looping animation, 1308—1309 Loaded event, 1173, 1174, 1278, 1288, 1289, loops. See iteration constructs 1311, 1359 loose resources, WPF LoadExternalModule( ) method, 622, 623 configuring, 1287 LoadFrom( ) method, 554, 596 including files in project, 1286—1287 loading lstTextBoxData control, 1431 assemblies, into custom application domains, 645 images programmatically, 1288—1289 ■M InkCanvas data, 1226—1227 XML content, 1006 M command, 1257 Local Area Network (LAN), 1019 MacDonald, Matthew, 1395 local variables machine.config file, 1051, 1063, 1503, 1505 accessing, C#, 429—430 MachineName class, 1031 declaring in CIL, 680—681 MachineName property, mapping parameters to in CIL, 681 System.Diagnostics.Process class, LocalBuilder member, 689 628
1650
INDEX ■
MachineName property, MainWindow.Designer.cs file, 1520, 1523 System.Environment class, 81 MainWindow.g.cs file, 1150, 1165 magic numbers, 146 MainWindowTitle property, MagicEightBallService class, 1033, 1052 System.Diagnostics.Process class, MagicEightBallServiceClient application, 629 1046 MainWindow.xaml file, 1146, 1149, 1151, MagicEightBallServiceClient project, 1048, 1165, 1173, 1174, 1294, 1366 1075 Make Into UserControl option, 1365 MagicEightBallServiceClient.exe.config Make property, 1110 file, 1050 MakeACar( ) method, 291, 292, 293 MagicEightBallServiceHost project, 1036, MakeColumn column, 934 1045, 1051 MakeNewAppDomain( ) method, 645 MagicEightBallServiceHost.exe Manage Help Settings tool, 68 application, 1059 managed attributes, 675 MagicEightBallServiceHTTP directory, managed code, 10 1036, 1045, 1048 managed heap, 289, 291, 292, 293, 294 MagicEightBallServiceHTTPDefaultBindin managed resources, 311 gs project, 1057 ManagedThreadId property, 731 MagicEightBallServiceLib namespace, Manager class, 226, 227, 228 1036 Manager object, 229 MagicEightBallServiceLib project, 1032, Manager type, 229, 230 1036 MANIFEST assembly, 544, 712 MagicEightBallServiceLib.dll assembly, MANIFEST data, 542 1036, 1049 MANIFEST icon, 35, 542 MagicEightBallTCP project, 1050 MapPath( ) method, 1418 main menu system, 1552—1553 mapping database names to friendly Main( ) method names, 916 implementing, 872 Mapping Details window, 967, 968, 969 Program class, 34 mappings, viewing, 967 variations on, 75—76 Margin property, 1195 WPF application, 626 markup, 1119 MainControl.xaml file, 1357 markup extensions, XAML, 1163—1165 MainForm class, 905, 906, 989 markup tags, 1440 MainForm_Load( ) method, 937 MarkupExtension class, 1163 MainForm.cs file, 763, 920 massive numerical value, 96 MainMenuStrip property, 1516 master constructor, 177, 178, 179, 201 MainWindow class *.master file, 1442, 1444, 1446, 1447, 1448 adding code file for, 1165 master pages defining, 1146—1147 AdRotator widget, 1447—1448 MainWindow property, 1129, 1137 bread crumbs, establishing with MainWindow type, 1516, 1535, 1553, 1555 SiteMapPath type, 1447 MainWindow_Paint( ) method, 1549 overview, 1442—1444 MainWindow.baml file, 1151 TreeView control site navigation Logic, MainWindow.cs file, 1520, 1534, 1549, 1552 1445—1447 MainWindow.cs icon, 1520 Master property, 1450
1651
INDEX ■
<%@Master%> directive, 1443 member parameters, defining in CIL, 676— MasterPage class, 1443 677 MasterPageFile attribute, 1402, 1449 member shadowing, 245—247 MasterPageFile property, 1417 member variables, 167 MasterPage.master file, 1443 MemberInfo class, System.Reflection Math class, 181 Namespace, 587 MathClient application, 1067 members, 22, 374 MathClient project, 1070, 1075 MemberType property, MethodBase MathExtensions class, 469 object, 268 MathLib.dll code library, 43 MemberwiseClone( ) method, 252, 349, MathLibrary assembly, 574 351, 353, 354 MathLibrary project, 711 MemoryStream class, 776 MathLibrary.dll assembly, 711, 712 MemoryStream object, 1234 MathMessage delegate, 435 Menu class, 1196 MathService.cs file, 1058 Menu control, 1439, 1445, 1446 MathServiceLibrary namespace, 1057, Menu item, 1447 1058 Menu property, 1530 MathServiceLibrary project, 1057 menu systems MathServiceLibrary.dll assembly, 1062 building visually, 1522—1524 MathWindowsServiceHost project, 1062, building window frame using nested 1066, 1067 panels, 1196—1197 MathWinService.cs file, 1062
1637
INDEX ■
HorizontalContentAlignment property, HttpApplicationState object, 1484, 1485, Control Type, 1133 1488 HorseAndBuggy class, 607 HttpApplicationState type, 1482, 1483, HorseAndBuggy type, 607 1484, 1486, 1487, 1488, 1489
1638
INDEX ■
widgets, 1476 Icon type, 1547 Hypertext Transfer Protocol (HTTP) IContextProperty interface, 651 overview, 1379 ICreateErrorInfo interface, 261 request/response cycle, 1380 ICustomFormatter interface, 85 requests, incoming, 1417—1420 ID attribute, 1397 response, outgoing, 1421—1423 Id member, ProcessThread type, 633 stateless protocols, 1380 ID property, 198, 200, 628, 1429, 1432 IDataAdapter interface, 828, 835 IDataAdapter type, System.Data ■I namespace, 832 IDataParameter interface, 828, 834—835 I command, 872 IDataParameter type, System.Data -i command, 566 namespace, 832 i parameter, 433 IDataReader interface, 827, 836 i variable, 682, 683 IDataReader type, System.Data tag, 1386 namespace, 832 IAdvancedDraw interface, 340 IDataReader.IsDBNull( ) method, 837 IAppFunctionality interface, 619, 620, 622 IDataRecord interface, 827, 836 IAsyncResult compatible object, 733 IDbCommand interface, 827, 834 IAsyncResult interface, 399, 734, 735, 774 IDbCommand type, System.Data IAsyncResult parameter, 732, 736, 738, 739 namespace, 832 IAsyncResult-compatible object, 732 IDbConnection interface, 321, 327, 827, IAsyncResult-compatible parameter type, 833 732 IDbConnection parameter, 837 IAutoLotService.cs file, 1072 IDbDataAdapter interface, 828 IBasicMath class, 1054 IDbDataAdapter type, System.Data IBasicMath interface, 469 namespace, 833 IBasicMath.cs file, 1057 IDbDataAdapterinterface, 835 IClassFactory interface, 7 IDbDataParameter interface, 828, 834—835 ICloneable class, 323 IDbTransaction interface, 828, 834, 878, ICloneable interface, 158, 323, 349—354, 879 362 IDbTransaction type, System.Data ICloneableExample application, 323 namespace, 833 ICloneableExample project, 324 IDE (integrated development ICollection interface, 362, 377, 378 environment), 932, 996, 1024, ICollection
1639
INDEX ■
IDisposable interface, 289, 305, 306, 307, IL (Intermediate Language), 12, 13 308, 309 *.il file, modifying, 662—663 IDraw3D interface, 331, 332, 333 ilasm compiler, Mono, 1569 IDrawable interface, 339, 341, 393 ilasm utility, Mono, 1571 IDropTarget interface, 322 ilasm.exe compiler, 666 IDynamicObject interface, 709 ildasm.exe file IEightBall interface, 1033, 1046 compiling CIL code using, 663—664 IEnumerable interface, building exploring assemblies using building iterator methods with yield overview, 33 keyword, 346 viewing assembly metadata, 35 building named iterator, 347—348 viewing Common Intermediate internal representation of iterator Language (CIL) code, 34 method, 348—349 viewing type metadata, 34 overview, 343—345 ILGenerator class, 691, 696, 697 IEnumerable type, 504 ILGenerator member, 689 IEnumerable
1640
INDEX ■
implements attribute, 655, 669, 670 index operator ([]), accessing items from implements clause, 670 arrays, 439 Implements keyword, 620 indexer methods implicit cast, 248 definitions on interface types, 444 implicit conversion function of, 439 routines, 458—459 multiple dimensions, 443—444 when required, 454 overloading, 443 implicit keyword, 455, 456, 459 overview, 439—440 implicit load, 554 string values, 441—442 implicit typing, 113, 701, 702 IndexOutOfRangeException class, 260 implicitly pop, 680 IndexOutOfRangeException type, 262 implicitly sealed, 223 infrastructure, adding to MainWindow implicitly typed local arrays, 139 type, 1555 implicitly typed local variables inheritance. See also polymorphism are strongly typed data, 115 base class/derived class casting rules overview, 112—113 is keyword, 250 restrictions on, 114—115 as keyword, 249 usefulness of, 116 overview, 247—248 ImplicitlyTypedLocalVars project, 112, 117 basic mechanics of <%@Import%> directives, 1398, 1402, 1403 multiple base classes, 222
1641
INDEX ■
overriding system.Object.ToString( in-memory representation, 9 ), 254 inner exceptions, 281 overview, 250—253 innerEllipse object, 1339 testing modified person class, 257— InnerException property, 263, 281 258 in/out parameter, 871 testing your modified person class, in-place editing, enabling, 1454 256 input button, setting default, 1541 inheritance chain, 615, 1416 input parameter, 78, 871 Inheritance icon, Class Designer Toolbox, input/output (I/O), 8 66 INSERT command, 914 Inheritance Picker dialog box, 1544 Insert( ) method, 97, 365, 380, 441, 1489, Inherited Form icon, 1543 1490 Inherited property, 612 Insert request, 861 Inherits attribute, 1402, 1409 Insert Snippet option, 63 Inherits keyword, 549 Insert Standard Items option, 1522 init attribute, 681 Insert statement, 862, 863, 955, 974, 1450 Init event, 1423, 1476 InsertAuto( ) method, 863, 864, 865, 868, InitClass( ) method, 934 875, 876, 1074 InitDAD( ) method, Program class, 643 InsertCar( ) method, 1072, 1073 Initial Catalog name, 854 InsertCommand property, 914, 918, 949 initial class types, 917 Insert/Delete logic, 882 InitializeComponent( ) method, 1151, InsertNewCar( ) method, 875—876 1153, 1165, 1203, 1520, 1521, 1523, InsertNewElement( ) method, 1008 1524 installing InitializeCorrelation activity, WF 4.0, 1090 Mono, 1565—1568 InitialValue property, 1459 strongly named assemblies to GAC, Ink API controls, 1183 565—566 Ink API support types, 1183 Windows service, 1066—1067 Ink API tab, WPF InstallSqlState.sql file, 1502 ComboBox control, 1224—1226 installutil MathWindowsServiceHost.exe InkCanvas control, 1222—1227 command, 1066 overview, 1216 instance attribute, 675 RadioButton control, 1220—1222 instance data, 182 ToolBar, 1217—1219 instance level, invoking extension ink controls, WPF, 1182—1183 methods on, 463 Ink mode, 1223 int data type, 86, 87, 92, 96, 106, 107, 108, Ink Mode! value, 1218 112, 116, 145 InkCanvas control, WPF, 1222—1227 int parameters, 106 InkCanvasEditingMode enumeration, 1223 int type, 356 inkRadio control, 1219 int variable, 107, 363, 364, 1289 inkToolbar control, 1217 intArray declaration, 138 inkToolbar node, 1217 IntCollection class, 369 inline elements, WPF, 1227 integer (0), 1335 inline menu editor, 1522, 1523 Integer data type, 135, 1479 in-memory data allocation, 183, 184
1642
INDEX ■
integrated development environment interface types vs. abstract base (IDE), 932, 996, 1024, 1025, 1379, classes, 322—325 1381, 1382, 1386, 1396, 1410 overview, 321 IntelliSense, 136, 466—467, 704 Interlocked class, 740, 756, 757 IntelliSense window, 423 Interlocked.CompareExchange( ) method, interactive graphical data, 1246 757 interface attribute, 670 Interlocked.Exchange( ) method, 757 interface implementation, 336, 337, 339, Interlocked.Increment( ) method, 757 342 Intermediate Language (IL), 12, 13 interface keyword, 20, 325 Intermediate Language Disassembler Interface member, 695 utility, 33 interface types internal data, of objects, 194 Common Type System (CTS), 20 internal keyword, 20, 125, 193, 194, 545 definitions on, 444 internal modifier, 193, 194 extending, 469—470 internal reference counter, 292 InterfaceExtensions project, 469, 470 internal representation InterfaceHierarchy application, 339 of anonymous types, 474—475 InterfaceHierarchy project, 340 of overloaded operators, 451—452 InterfaceNameClash application, 336 InternalsVisibleToAttribute class, 545 InterfaceNameClash project, 339 International Organization for interfaces Standardization (ISO), 1562 building cloneable objects, 349—354 Internet Information Services (IIS), 1025, building comparable objects, 354—359 1026, 1036, 1037, 1040, 1071, 1074, building enumerable types 1379, 1381, 1382 building iterator methods with yield Internet Protocol (IP) address, 1380, 1381, keyword, 346 1418 building named iterator, 347—348 interop assemblies, 10, 714, 717 internal representation of an interop library, 716 iterator method, 348—349 interoperability assemblies, 714, 716 overview, 343—345 interoperability data, 716 custom, defining, 325—327 interoperating, 1121 defining and implementing in CIL, 670 Interrupt( ) method, 742 designing hierarchies, 339—342 Intersect( ) method, 515 explicit implementation of, resolving Intersect<>( ) method, 509 name clashes via, 336—339 into operator, 509 generic, specifying type parameters for, intrinsic control command objects, WPF, 374—375 1201 implementing, 327—328 intVal variable, 757 invoking interface members at object Invalidate( ) method, 1246, 1529, 1551, level, 329—331 1556, 1557 as parameters, 331—333 invalidating form's client area, 1551 as return values, 333 InvalidCastException exception, 329, 365 types InvalidOperationException errors, 636 arrays of, 334 Inventories property, 959 Inventory database, 973
1643
INDEX ■
Inventory objects, 984, 989, 1242 invoking services asynchronously from Inventory property, 932, 934 clients, 1067—1069 Inventory schema, 954 invoking statically, 464 Inventory table, 840—842, 850, 853, 860, I/O (input/output), 8 861, 862, 863, 864, 865 I/O and object serialization Inventory table icon, 842 abstract stream class, 792—794 Inventory variable, 1107 BinaryWriters and BinaryReaders Inventory.aspx file, 1446, 1450 classes, 799—801 Inventory.aspx page, 1454 configuring objects for serialization InventoryDAL class, 862, 863, 864, 865, overview, 806 874, 875, 880—882 public fields, private fields, and InventoryDAL object, 863, 872 public properties, 807—808 InventoryDAL type, 867, 870, 875, 1492 serializable types, 807 InventoryDALDisconnectedGUI customizing Soap/Binary serialization application, 920 processes InventoryDALDisconnectedGUI project, overview, 818—819 921 using attributes, 823 InventoryDALDisLayer class, 917, 920, using ISerializable interface, 820— 1106 822 InventoryDALDisLayer object, 918, 921 Directory type, 782—783 InventoryDALDisLayer variable, 1106, Directory(Info) and File(Info) types, 1107 777—778 InventoryDataSet class, 932, 933, 936 DirectoryInfo type InventoryDataSet.Designer.cs file, 933 creating subdirectories with, 781— InventoryDataSet.xsd file, 933 782 InventoryDataTable class, 934, 936, 941 enumerating files with, 780—781 InventoryDataTable variable, 934 overview, 778—779 InventoryEDMConsoleApp application, DriveInfo class type, 783—784 961 file type, 789—791 InventoryEDMConsoleApp example, 979 FileInfo class InventoryEDM.Designer.cs file, 970 AppendText( ) method, 789 InventoryEDM.edmx file, 962, 968 Create( ) method, 786 InventoryEDM.edmx node, 970 CreateText( ) method, 789 InventoryRecord class, 1072, 1074 Open( ) method, 786—788 InventoryRow class, 934 OpenRead( ) method, 788 InventoryTableAdapter class, 936, 937, 940 OpenText( ) method, 789 Inventory.xlsx file, 721, 1007—1008 OpenWrite( ) method, 788 invisible brushes, 1249 overview, 785 Invoke( ) method, 398, 399, 400, 403, 602, files, watching programmatically, 801— 711, 730, 1084, 1086 804 InvokeMember( ) method, System.Type object serialization, 804—806 class, 588 overview, 775 InvokeMethod activity, 1091, 1094—1095, serialization formatters 1096, 1098, 1099 IFormatter and IRemotingFormatter invoking extension methods, 463—464 interfaces, 809—810
1644
INDEX ■
overview, 808 IService1.cs file, 1057 type fidelity among formatters, 810— IService.cs file, 1072 811 ISet
1645
INDEX ■
1646
INDEX ■
L suffix, 87 invoking methods with parameters, Label class, 912, 920, 925, 1241, 1396, 1397, 603—604 1399, 1403, 1404, 1408 overview, 600 Label control, 1227, 1240, 1331, 1354, 1434, System.Activator class, 601—602 1436, 1439, 1455, 1485, 1495 LateBindingApp application, 601 Label object, 1236, 1309 LateBindingWithDynamic application, 711 Label type, 1304, 1456, 1506 LateBindingWithDynamic project, 711, Label widget, 322, 1422, 1433, 1474 712
1647
INDEX ■
.NET code, 581 LineGeometry object, 1255 COM type, 581 lines consuming workflow, 1112—1114 adding to canvas, 1249—1252 of extension, 467—468 removing from canvas, 1252—1253 external code, 1083 LinkedList
1648
INDEX ■
basic selection syntax, 510—511 vs. DOM models, 995—996 LINQ as better Venn diagramming overview, 993—994 tool, 515—516 Visual Basic (VB) literal syntax, 996— obtaining counts using enumerable, 997 513 XML documents obtaining subsets of data, 511 building UI of LINQ to XML App, overview, 508—509 1007 projecting new data types, 512—513 defining LINQ to XML Helper class, removing duplicates, 516 1008—1009 reversing result sets, 514 importing Inventory.xml files, 1007— sorting expressions, 514 1008 internal representation of LINQ query overview, 1006 statements rigging up UI to Helper class, 1009— building query expressions using 1011 enumerable type and anonymous LINQ-compatible datatables, obtaining, methods, 520 946—947 building query expressions using LinqOverArray application, 496 enumerable type and lambda LinqOverArray project, 503 expressions, 519—520 LinqOverArrayUsingEnumerable project, building query expressions using 522 enumerable type and raw LinqOverCollections project, 505, 508 delegates, 521—522 LinqOverDataSet example, 949 building query expressions with LinqOverDataTable( ) method, 945 query operators, 518 LinqRetValues application, 504 overview, 517 LinqRetValues project, 505 LINQ specific programming constructs LinqToDataSetApp application, 946 anonymous types, 493 LinqToXmlFirstLook application, 993 extension methods, 492—493 LinqToXmlObjectModel class, 1008 implicit typing of local variables, 490 LinqToXmlWinApp application, 1007 lambda expressions, 491—492 LinqUsingEnumerable application, 518 object and collection initialization Linux operating system, executing syntax, 491 Windows Forms application overview, 489 under, 1580 returning result of LINQ query, 503—505 List block, 1231 role of LINQ, 493—495 List class, 1230 LINQ to XML List element, 1227, 1231 System.Xml.Linq namespaces, 997— List type, 1227 1002 List<> class, 370 XElement and XDocument objects List<> object, 371, 372 generating documents from arrays List
1649
INDEX ■
List
1650
INDEX ■
MachineName property, MainWindow.Designer.cs file, 1520, 1523 System.Environment class, 81 MainWindow.g.cs file, 1150, 1165 magic numbers, 146 MainWindowTitle property, MagicEightBallService class, 1033, 1052 System.Diagnostics.Process class, MagicEightBallServiceClient application, 629 1046 MainWindow.xaml file, 1146, 1149, 1151, MagicEightBallServiceClient project, 1048, 1165, 1173, 1174, 1294, 1366 1075 Make Into UserControl option, 1365 MagicEightBallServiceClient.exe.config Make property, 1110 file, 1050 MakeACar( ) method, 291, 292, 293 MagicEightBallServiceHost project, 1036, MakeColumn column, 934 1045, 1051 MakeNewAppDomain( ) method, 645 MagicEightBallServiceHost.exe Manage Help Settings tool, 68 application, 1059 managed attributes, 675 MagicEightBallServiceHTTP directory, managed code, 10 1036, 1045, 1048 managed heap, 289, 291, 292, 293, 294 MagicEightBallServiceHTTPDefaultBindin managed resources, 311 gs project, 1057 ManagedThreadId property, 731 MagicEightBallServiceLib namespace, Manager class, 226, 227, 228 1036 Manager object, 229 MagicEightBallServiceLib project, 1032, Manager type, 229, 230 1036 MANIFEST assembly, 544, 712 MagicEightBallServiceLib.dll assembly, MANIFEST data, 542 1036, 1049 MANIFEST icon, 35, 542 MagicEightBallTCP project, 1050 MapPath( ) method, 1418 main menu system, 1552—1553 mapping database names to friendly Main( ) method names, 916 implementing, 872 Mapping Details window, 967, 968, 969 Program class, 34 mappings, viewing, 967 variations on, 75—76 Margin property, 1195 WPF application, 626 markup, 1119 MainControl.xaml file, 1357 markup extensions, XAML, 1163—1165 MainForm class, 905, 906, 989 markup tags, 1440 MainForm_Load( ) method, 937 MarkupExtension class, 1163 MainForm.cs file, 763, 920 massive numerical value, 96 MainMenuStrip property, 1516 master constructor, 177, 178, 179, 201 MainWindow class *.master file, 1442, 1444, 1446, 1447, 1448 adding code file for, 1165 master pages defining, 1146—1147 AdRotator widget, 1447—1448 MainWindow property, 1129, 1137 bread crumbs, establishing with MainWindow type, 1516, 1535, 1553, 1555 SiteMapPath type, 1447 MainWindow_Paint( ) method, 1549 overview, 1442—1444 MainWindow.baml file, 1151 TreeView control site navigation Logic, MainWindow.cs file, 1520, 1534, 1549, 1552 1445—1447 MainWindow.cs icon, 1520 Master property, 1450
1651
INDEX ■
<%@Master%> directive, 1443 member parameters, defining in CIL, 676— MasterPage class, 1443 677 MasterPageFile attribute, 1402, 1449 member shadowing, 245—247 MasterPageFile property, 1417 member variables, 167 MasterPage.master file, 1443 MemberInfo class, System.Reflection Math class, 181 Namespace, 587 MathClient application, 1067 members, 22, 374 MathClient project, 1070, 1075 MemberType property, MethodBase MathExtensions class, 469 object, 268 MathLib.dll code library, 43 MemberwiseClone( ) method, 252, 349, MathLibrary assembly, 574 351, 353, 354 MathLibrary project, 711 MemoryStream class, 776 MathLibrary.dll assembly, 711, 712 MemoryStream object, 1234 MathMessage delegate, 435 Menu class, 1196 MathService.cs file, 1058 Menu control, 1439, 1445, 1446 MathServiceLibrary namespace, 1057, Menu item, 1447 1058 Menu property, 1530 MathServiceLibrary project, 1057 menu systems MathServiceLibrary.dll assembly, 1062 building visually, 1522—1524 MathWindowsServiceHost project, 1062, building window frame using nested 1066, 1067 panels, 1196—1197 MathWinService.cs file, 1062