- •brief contents
- •about this book
- •The Windows Forms namespace
- •Part 1: Hello Windows Forms
- •Part 2: Basic Windows Forms
- •Part 3: Advanced Windows Forms
- •Who should read this book?
- •Conventions
- •Action
- •Result
- •Source code downloads
- •Author online
- •acknowledgments
- •about .NET
- •Casting the .NET
- •Windows Forms overview
- •about the cover illustration
- •Hello Windows Forms
- •1.1 Programming in C#
- •1.1.1 Namespaces and classes
- •1.1.2 Constructors and methods
- •1.1.3 C# types
- •1.1.4 The entry point
- •1.1.5 The Application class
- •1.1.6 Program execution
- •1.2 Adding controls
- •1.2.1 Shortcuts and fully qualified names
- •1.2.2 Fields and properties
- •1.2.3 The Controls property
- •1.3 Loading files
- •1.3.1 Events
- •1.3.2 The OpenFileDialog class
- •1.3.3 Bitmap images
- •1.4 Resizing forms
- •1.4.1 Desktop layout properties
- •1.4.2 The Anchor property
- •1.4.3 The Dock property
- •1.5 Recap
- •2.1 Programming with Visual Studio .NET
- •2.1.1 Creating a project
- •Action
- •Result
- •2.1.2 Executing a program
- •Action
- •Result
- •2.1.3 Viewing the source code
- •View the code generated by Visual Studio .NET
- •Action
- •Result
- •2.2 Adding controls
- •2.2.1 The AssemblyInfo file
- •Action
- •Results
- •2.2.2 Renaming a form
- •Action
- •Result
- •2.2.3 The Toolbox window
- •Action
- •Result
- •2.3 Loading files
- •2.3.1 Event handlers in Visual Studio .NET
- •Action
- •Result
- •2.3.2 Exception handling
- •Action
- •Result
- •Action
- •Results and Comments
- •2.4 Resizing forms
- •2.4.1 Assign the Anchor property
- •Action
- •Result
- •2.4.2 Assign the MinimumSize property
- •Action
- •Result
- •2.5 Recap
- •Basic Windows Forms
- •Menus
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •3.3 Click events
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •3.5 Context menus
- •Action
- •Result
- •Action
- •Result
- •3.6 Recap
- •Status bars
- •4.1 The Control class
- •4.2 The StatusBar class
- •Action
- •Result
- •Action
- •Result
- •4.3.1 Adding panels to a status bar
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •4.5 Recap
- •Reusable libraries
- •5.1 C# classes and interfaces
- •5.2 Class libraries
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •5.3 Interfaces revisited
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •5.4 Robustness issues
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Common file dialogs
- •Action
- •Results
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •6.3 Paint events
- •Action
- •Result
- •Action
- •Result
- •6.4 Context menus revisited
- •Action
- •Result
- •Action
- •Result
- •6.5 Files and paths
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •6.6 Save file dialogs
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •6.7 Open file dialogs
- •Action
- •Result
- •Action
- •Result
- •6.8 Recap
- •Drawing and scrolling
- •7.1 Form class hierarchy
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •7.4 Panels
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Dialog boxes
- •8.1 Message boxes
- •Action
- •Result
- •Action
- •Result
- •8.1.4 Creating A YesNoCancel dialog
- •Action
- •Result
- •Action
- •Result
- •8.2 The Form.Close method
- •8.2.1 The relationship between Close and Dispose
- •Action
- •Result
- •8.3 Modal dialog boxes
- •Action
- •Result
- •Action
- •Result
- •8.3.2 Preserving caption values
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Basic controls
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •9.1.2 Creating a derived form
- •Action
- •Result
- •9.2 Labels and text boxes
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •9.3.6 Adding AlbumEditDlg to our main form
- •Action
- •Result
- •Action
- •Result
- •9.4 Recap
- •List controls
- •10.1 List boxes
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •10.2 Multiselection list boxes
- •10.2.1 Enabling multiple selection
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •10.3 Combo boxes
- •Action
- •Result
- •Action
- •Result
- •10.4 Combo box edits
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •10.5 Owner-drawn lists
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •More controls
- •Action
- •Result
- •Action
- •Result
- •11.2 Tab pages
- •Action
- •Result
- •Action
- •Result
- •11.3.1 Dates and times
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •11.5 Recap
- •A .NET assortment
- •12.1 Keyboard events
- •Action
- •Result
- •Action
- •Result
- •12.2 Mouse events
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •12.3 Image buttons
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •12.4 Icons
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •12.5 Recap
- •Toolbars and tips
- •13.1 Toolbars
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •13.4.2 Creating tool tips
- •Action
- •Result
- •Action
- •Result
- •Advanced Windows Forms
- •List views
- •14.2 The ListView class
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •14.2.3 Populating a ListView
- •Action
- •Result
- •Action
- •14.3 ListView columns
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •14.6 Recap
- •Tree views
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •15.3 Dynamic tree nodes
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •15.4 Node selection
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •15.5 Fun with tree views
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Multiple document interfaces
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •16.3 Merged menus
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •16.4 MDI children
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •16.5 MDI child window management
- •Action
- •Result
- •Action
- •Result
- •16.6 Recap
- •Data binding
- •17.1 Data grids
- •Action
- •Result
- •Action
- •Result
- •17.2 Data grid customization
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Odds and ends .NET
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •18.2 Timers
- •Action
- •Result
- •Action
- •Result
- •18.3 Drag and drop
- •Action
- •Result
- •Action
- •Result
- •18.4 ActiveX controls
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •Action
- •Result
- •18.5 Recap
- •C# primer
- •A.1 C# programs
- •A.1.1 Assemblies
- •A.1.2 Namespaces
- •A.2 Types
- •A.2.1 Classes
- •A.2.2 Structures
- •A.2.3 Interfaces
- •A.2.4 Enumerations
- •A.2.5 Delegates
- •A.3 Language elements
- •A.3.1 Built-in types
- •A.3.2 Operators
- •A.3.3 Keywords
- •A.4 Special features
- •A.4.1 Exceptions
- •A.4.2 Arrays
- •A.4.3 Main
- •A.4.4 Boxing
- •A.4.5 Documentation
- •.NET namespaces
- •B.1 System.Collections
- •B.2 System.ComponentModel
- •B.3 System.Data
- •B.4 System.Drawing
- •B.5 System.Globalization
- •B.6 System.IO
- •B.7 System.Net
- •B.8 System.Reflection
- •B.9 System.Resources
- •B.10 System.Security
- •B.11 System.Threading
- •B.12 System.Web
- •B.13 System.Windows.Forms
- •B.14 System.XML
- •Visual index
- •C.1 Objects
- •C.2 Marshal by reference objects
- •C.3 Components
- •C.4 Common dialogs
- •C.7 Event data
- •C.8 Enumerations
- •For more information
- •bibliography
- •Symbols
- •Index
In this section we will simply move our existing DataGrid control into an Album tab, and create a Photo tab containing the controls shown in the figure. The following steps implement this change.
Set the version number of the MyAlbumData application to 17.4.
CREATE THE CONTROLS WITHIN A TAB CONTROL OBJECT
|
|
|
Action |
|
|
Result |
|
|
|
|
|
|
|
|
|
1 |
|
In the MainForm.cs [Design] window, |
|
||||
|
|
alter the Size property for the form to |
|
||||
|
|
be 450×350. |
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
Move the existing DataGrid control to |
|
||||
|
|
exist within a tab page. |
|
|
|
||
|
|
How-to |
|
|
|
|
|
|
|
a. Create a tab control containing two |
|
||||
|
|
tab pages. |
|
|
|
|
|
|
|
b. Set their properties as shown. |
|
||||
|
|
c. Move the data grid into the Album |
|
||||
|
|
tab page, and set its Dock property |
|
||||
|
|
to Fill. |
|
|
|
|
|
|
|
|
Settings |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Control |
|
Property |
Value |
|
|
|
|
TabControl |
|
(Name) |
tcMain |
|
|
|
|
|
|
Anchor |
Top, Bottom, |
|
|
|
|
|
|
|
Left, Right |
|
|
|
|
TabPage (Album) |
|
(Name) |
tabAlbum |
|
|
|
|
|
|
Text |
Album |
|
|
|
|
TabPage (Photo) |
|
(Name) |
tabPhoto |
|
|
|
|
|
|
Text |
Photo |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
588 |
CHAPTER 17 DATA BINDING |
CREATE THE CONTROLS WITHIN A TAB CONTROL OBJECT (continued)
|
|
|
Action |
|
|
Result |
|
|
|
|
|
|
|
3 |
Create and position the controls for |
|
||||
|
the Photo tab page as shown in the |
|
||||
|
graphic. |
|
|
|
|
|
|
|
Note: In the rather long Settings table |
|
|||
|
|
here, the Label controls are not |
|
|||
|
|
shown. For these controls, use the |
|
|||
|
|
default name, the text shown in the |
|
|||
|
|
graphic, and the same Anchor prop- |
|
|||
|
|
erty as the related control. |
|
|||
|
|
Also note that all TextBox controls |
|
|||
|
|
should have their Text property set to |
|
|||
|
|
an empty string. |
|
|
|
|
|
|
|
Settings |
|
|
|
|
|
|
|
|
|
|
|
|
Control |
Property |
Value |
|
|
|
|
FileName |
(Name) |
txtFileName |
Note: When assigning the Anchor property, |
|
|
|
you may find it easier to first create and posi- |
||||
|
|
|
ReadOnly |
True |
||
|
|
|
tion the controls and then use the following |
|||
|
|
PictureBox |
(Name) |
pboxPhoto |
||
|
|
technique: |
||||
|
|
|
Anchor |
Top, Bottom, |
||
|
|
|
a. Select a group of related controls by drag- |
|||
|
|
|
|
Left, Right |
||
|
|
|
|
ging the mouse over a region of the form. |
||
|
|
|
BorderStyle |
FixedSingle |
||
|
|
|
b. Assign the Anchor property for all controls |
|||
|
|
Prev |
(Name) |
btnPrev |
||
|
|
at once. |
||||
|
|
|
Anchor |
Bottom, Left |
||
|
|
|
|
|||
|
|
|
Text |
Pre&v |
|
|
|
|
Next |
(Name) |
btnNext |
|
|
|
|
|
Anchor |
Bottom, Right |
|
|
|
|
|
Text |
Nex&t |
|
|
|
|
Caption |
(Name) |
txtCaption |
|
|
|
|
|
Anchor |
Top, Right |
|
|
|
|
Photo- |
(Name) |
txtPhoto- |
|
|
|
|
grapher |
|
grapher |
|
|
|
|
|
Anchor |
Top, Right |
|
|
|
|
Date Taken |
(Name) |
dtpDateTaken |
|
|
|
|
|
Anchor |
Top, Right |
|
|
|
|
|
Format |
Short |
|
|
|
|
Notes |
(Name) |
txtNotes |
|
|
|
|
|
Anchor |
Top, Bottom, |
|
|
|
|
|
|
Right |
|
|
|
|
|
Multiline |
True |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SIMPLE DATA BINDING |
589 |
|
CREATE THE CONTROLS WITHIN A TAB CONTROL OBJECT |
(continued) |
|
|
|
|
|
|
Action |
|
Result |
|
|
|
|
4 |
Assign the tab order for the controls |
|
|
|
within the Photo tab page as is shown |
|
|
|
in the graphic. |
|
|
|
|
|
|
That took a bit of work. As we mentioned earlier in the book, you can reduce the amount of time spent drawing forms in Visual Studio by sketching out your controls on paper before using Visual Studio. While not illustrated in these pages, I really did sketch the Photo tab page by hand before creating this page in Visual Studio .NET.
With our controls defined, we are ready for our data binding discussion.
17.4.2PERFORMING SIMPLE BINDING
The binding of controls to data involves four distinct roles, each with a corresponding class. These correspond to the work performed by the .NET Framework on behalf of bound controls, namely tracking which data has been bound to which control, managing a bound data source, tracking specific bindings to a control, and managing the actual bindings. A summary of these roles, along with the Windows Forms class and property related to these roles, is outlined in the following table:
Roles required for simple data binding
Role |
Class |
Accessing from Control class |
|
|
|
Tacking bound data |
BindingContext |
BindingContext property |
Managing a bound data |
BindingManagerBase |
Index into BindingContext collection: |
source |
|
BindingContext[ source ] |
|
|
|
|
|
BindingContext[ source, member ] |
Managing bindings |
ControlBindingsCollection |
DataBindings property |
Tracking a binding |
Binding |
Index into DataBindings collection: |
|
|
DataBindings[ property ] |
|
|
|
We will discuss these classes and properties in more detail as we build our example. As a brief explanation, the BindingContext class manages a collection of BindingManagerBase objects. While any control can create an instance of this class in its BindingContext property, the Form class creates one automatically to serve as the
590 |
CHAPTER 17 DATA BINDING |
default container for all data bound to the form. In our case, we will simply use the default BindingContext for our form, and not discuss this class in too much detail.
A single BindingManagerBase object exists for each bound data object. In our case, with a single PhotoAlbum object bound to our controls, our application will have a single BindingManagerBase created. For an object with multiple members, such as a database with multiple tables, a BindingManagerBase will exist for each member bound to a control.
A ControlBindingsCollection object contains the collection of actual bindings created for a control. The DataBindings property in the Control class contains the collection of these binding objects.
Each binding object is a Binding class instance. The Binding class permits any property of any control to be bound to any column or property of a data source. We will see this in our application shortly.
Let’s discuss the previous table from the bottom up, beginning with the Binding class. Typically, it is not necessary to access this class directly. Even so, it is likely useful to see the properties that make up each individual binding, so a summary of this class appears in .NET Table 17.6. Note that the possible data sources for simple data binding correspond to those shown earlier in the chapter for the DataGrid control.
As you can see, this class is fairly generic, and permits any property to be bound to pretty much anything. The Format and Parse events can even be used to specify exactly how this binding will take place when converting between the data source and the control’s property.
If you are thoroughly confused at this point, don’t fret. We will lay this out step by step for our application, which should aid your understanding. Let’s start with a summary of exactly what should be bound to what. The following table shows our controls, the property in each control that we would like to bind, and the member of the Photograph object within our PhotoAlbum data source that can provide this value.
Details of our initial data binding approach
Control name |
Control property to bind |
Photograph property for binding source |
|
|
|
txtFileName |
Text |
FileName |
txtCaption |
Text |
Caption |
dtpDateTaken |
Value |
DateTaken |
txtNotes |
Text |
Notes |
pboxPhoto |
Image |
Image |
|
|
|
SIMPLE DATA BINDING |
591 |
.NET Table 17.6 Binding class
The Binding class represents a simple data binding between a data source entry and a Windows Form control. The Binding instances defined for a control are contained by the DataBindings property of that control. This class is part of the System.Windows.Forms namespace.
|
Binding |
Create a new Binding instance. This has the |
|
Public |
|
following signature: |
|
|
|
||
Constructor |
|
Binding(string propertyName, |
|
|
|
object dataSource, |
|
|
|
string dataMember); |
|
|
|
|
|
|
BindingManagerBase |
Gets the BindingManagerBase class instance |
|
|
|
for the data source used by this binding. |
|
|
BindingMemberInfo |
Gets the BindingMemberInfo structure |
|
|
|
containing information about the data member |
|
|
|
used by this binding. This value is created using |
|
|
|
the dataMember value passed to the Binding |
|
|
|
constructor. For a database source, this |
|
|
|
indicates the table and column that should be |
|
|
|
bound. For an IList source, this indicates the |
|
|
|
property member in the contained object that |
|
Public Properties |
|
should be bound. |
|
Control |
Gets the control that is the subject of this |
||
|
|||
|
|
binding. |
|
|
DataSource |
Gets the data source used by this binding, |
|
|
|
taken from the corresponding value passed to |
|
|
|
the Binding constructor. |
|
|
IsBinding |
Gets whether this binding is currently active. |
|
|
PropertyName |
Gets or sets the property name of the control |
|
|
|
that is the subject of this binding. This is taken |
|
|
|
from the corresponding value passed to the |
|
|
|
Binding constructor. |
|
|
|
|
|
|
Format |
Occurs when the value from the data source |
|
|
|
must be processed, or formatted, and assigned |
|
Public Events |
|
to the bound property in the control. |
|
Parse |
Occurs when the value from the control must |
||
|
|||
|
|
be processed, or parsed, and assigned to the |
|
|
|
appropriate entry in the data source. |
|
|
|
|
So let’s do this. We already have a PhotoAlbum field in our MainForm class, so we can bind these controls in our OnLoad method, as shown in the following table.
592 |
CHAPTER 17 DATA BINDING |