All errata for Windows Forms Programming with C# will be posted here.
If you discover any mistakes in the book, you may post them in the Author Online Forum for the book.
Section 1.4.1, Page 29:
In the table, the property "ShowInTaskBar" should be "ShowInTaskbar" (with a lower case B).
The Type for MinimizeBox should be "bool."
Section 2.2.1, Page 44:
The revision number is equal to the number of seconds since the previous midnight, local time, divided by 2 (not modulo 2 as I say in the book). This ensures the revision number is never larger than a 16-bit integer (I say 32-bit in the book, which is technically correct but not really what I wanted to say).
Section 2.2.2, Page 47:
In step 3, the "Replace All" does not change entries within the "#region" block of code. To make sure the "Replace All" changes the entries in the InitializeComponent() section, you will need to explicitly expand the #region section.
Section 2.2.3, Page 50:
In step 9, it incorrectly states that the TabIndex property is set to 1, when it should say:
"the TabIndex property for this control is set to 0...."
Section 2.3.2, Page 60:
In steps 2 and 3, the variable imgPhoto is used, instead of the
correct variable "pbxPhoto"
Section 2.4.2, Page 64:
The title in this Action-Result table should be "Set the MinimumSize property for the form"
Section 3.3.1, Page 85:
in step 2, at the bottom of the Result box, the generated C# method is shown as "protected". This should be "private," to match how Visual Studio .NET generates the code.
Section 3.3.2, Page 87:
in step 3, the generated method is shown as "protected." This should be "private" to match how Visual Studio .NET generates the code.
Section 3.4.1, Page 91:
In step 5, the method name "InitializeComponent" is
misspelled as "InidializeComponent."
Section 3.4.2, Page 94:
The code in the table here uses sender as a MenuItem object, while the code below the table uses sender as a Menu object. The correct code is the version below the table with sender as a Menu object. This becomes especially important in section 13.3.2 when creating a dropdown toolbar button that implicitly uses this same code. The use of Menu (rather than MenuItem) allows the code to work with any Menu object, most notably a ContextMenu instance.
Also, in step 3, the variable "imgPhoto" should be "pbxPhoto"
Section 4.4.2, Page 125:
In step 7, the variable name nSelectedImageMode is mistakenly
used in place of the correct "_selectedImageMode" variable.
Section 5.2.1, Pages 134-135:
Unfortunately, Visual Studio .NET Standard Edition ships without a class library template as described on these pages. This should be fixed in the future, but causes a problem here. To get around this, you can do one of two things. First choice is to download the online code for section 5.2 from this web site, and use this as the basis for your library. Another choice is to add this template to your Visual Studio .NET application. As of July 1, 2002, one way to do this is described at the link http://groups.google.com/groups?selm=O9vIryEACHA.2284%40tkmsftngp02.
Thanks to reader Angie Zimaro for discovering both the problem and the solution, and also for posting the solution to the online forum.
Section 5.4.1, page 152:
in step 2, the InvalidPhotoImage is introduced. On page 153, this property is repeated with the name InvalidImageBitmap. They should, of course, be the same throughout the chapter (InvalidPhotoImage).
in step 4, the comparison here should use the Image property rather than _bitmap to make sure both internal fields (_bitmap and _invalidImageBitmap) are assigned if necessary.
Section 5.4.2, page 157:
in step 2, the GetHashCode() function should use FileName.ToLower().GetHashCode() to be consistent with the Equals() method earlier in the section.
Section 5.4.3, Page 159:
in step 4, the _disposing field should be reset to false at the end of the if loop. This ensures that the album can be re-used in the future and properly disposed of.
Section 6.1.1, Page 163:
The menu structure table here lists 'File' as the first Menu Item for the File entry of the menu bar. This first entry should be 'New' as shown in Figure 6.1.
Section 6.5.1, Page 177:
In step 3, the '@' symbol is incorrectly called an ampersand. The ampersand is the '&' symbol, while '@' is informally referred to as an "at-sign."
Section 7.2.3, Page 204:
In the code listing, the use of the property "CurrentIndex"
should be 'CurrentPosition.' The correct line in this listing is
as follows:
_album.CurrentPosition+1, _album.Count);
Section 7.2.4, Page 208:
In step 7, it should say to "add a Scale To Fit menu to the top of the
Image menu within the View menu." (rather than
"the top of the View menu.")
Section 7.4, Page 221:
in step 4, the two "pnlPhoto.AutoScrollPosition..." lines in the ActualSize case block should be in bold.
Section 7.4.4, Page 222:
In step 6 of the Results, beneath the "Update the status bar." comment:
- the three status bar panels are missing "sb" in front.
("pnlFileName" should be "sbpnlFileName")- "
photo.Caption" should be "photo.FileName"- "
_album.CurrentIndex" should be "_album.CurrentPosition"
Section 8.3.3, Page 244:
The text for the first label should be set to "&Image", and the accompanying graphics should show the "I" character underlined (some do and some do not).
Section 8.4.4, Page 259, Step 7:
There are two problems in the ActualSize code here. An error is generated if the mouse moves over a portion of the panel that does not display the image, and the pixel value is not updated property during scrolling. The code here should be as follows:
case DisplayMode.ActualSize:
????// Panel coords equal image coords
????if (xPos >= bmp.Width || yPos >= bmp.Height)
????????return; // mouse outside image
????x = xPos - pnlPhoto.AutoScrollPosition.X;
????y = yPos - pnlPhoto.AutoScrollPosition.Y;
????break;
Section 9.2.1, Page 276:
in step 8, the underscore for "_CurrentVersion" is missing.
Section 9.2.1, Page 281:
In the middle of the first paragraph, "typing Alt-P for the Caption label" should be "typing Alt-T...."
Section 9.3.1, Page 294:
in steps 4 and 5, the underscore is missing from the "_CurrentVersion" constant.
Section 10.1.1, Page 321:
the code here does not actually refresh the display when you open a new album. Fix this by changing the code in step 16 to:
protected void UpdateList()
{
lstPhotos.DataSource = null;
lstPhotos.DataSource = _album;
}
Section 10.3.1, Page 333:
Figure 10.4 should end with "...required for the control on the form." The final "form." is missing.
Section 10.3.2, Page 337:
in step 2, the SelectedIndexChanged handler does not handle a value of -1. This was not a problem in .NET 1.0, but can cause problems in the newer 1.1 version in some situations. Insert the following code here:
// Make sure DataSource has been set
if (cmbxAlbums.SelectedIndex < 0)
return;
In step 1, change "SelectedItemChanged" to "SelectedIndexChanged."
Section 10.4.1, Page 340:
In step 2, "MaxDropDown" should be "MaxDropDownItems"
Section 10.5.1, Page 345:
in step 2, the value for the text property should be "&Thumbnails" (with an s).
Section 11.2.1, Page 362:
The code in the TRY IT! block incorrectly uses the System.EventHandler delegate rather than the correct PaintEventHandler. This code should look as follows:
// Assign a Paint event handler to draw this photo
newPage.Tag = photo;
newPage.Paint += new PaintEventHandler(this.newPage_Paint);
Section 11.3.1, Page 368:
In step 3, it says "MainForm.cs source file." This should be "PhotoEditDlg.cs source file."
Section 12.3.3, Page 405:
Note that the graphics files mentioned here are not provided with Visual Studio .NET Standard Edition. For Standard Edition users, the graphics can be downloaded from the Microsoft web site.
Section 12.4.1, Page 407:
In step 2, it says to assign the bitmap "BOOKS02.ICO." The correct bitmap (as shown in the graphic) is "BOOK02.ICO."
Section 13.4.2, Page 433:
In step 4, the reference to the control "dateTimeTaken"
should be "dtpTimeTaken."
Section 14.2.2, Page 446:
In step 3, the settings for the menuDetails menu is missing the
Text property setting, which should be set to "&Details"
Section 14.3.2, Page 453:
The TRY IT! section here says to "use this new method in the MainForm.OpenAlbum method of our application." This should instead say "the MainForm.LoadAlbumData method of our application."
Section 15.5.2, Page 517:
In step 3, the code is missing a way to enable the Properties menu when the TreeView is selected. The following code fixes this problem with the addition of a menuProperties.Enabled line:
private void menuEdit_Popup(object sender, System.EventArgs e)
{
??if (treeViewMain.Focused)
??{
????menuProperties.Enabled = (treeViewMain.SelectedNode != null);
????menuEditLabel.Enabled = (treeViewMain.SelectedNode != null);
????menuEditLabel.Text = "&Node";
??}
??else // assume ListView has focus
??{
????. . .
Section 15.5.2, Page 519:
in step 8, renaming an album in the ListView control does not properly update the TreeView.Tag entry. This code should read:
// Update the appropriate Tag property
if (item != null)
{
item.Tag = newFileName;
if (node != null)
{
node.Text = newName;
node.Tag = newFileName;
}
}
else if (node != null)
node.Tag = newFileName;
Section 16.1.3, Page 527:
The first sentence of this section ends in "at the same type" when it should read "at the same time."
Section 17.1.1, Page 568:
In step 3, the label text value should be "&Album:" to match the graphic (with the colon).
Section 17.4, Page 586:
in the code here, change "cmbxAlbum.DataMember" to "cmbxAlbum.DisplayMember."
Section 17.4.2, Page 590:
In the Role column of the table, "Tacking bound data" should be "Tracking bound data."
Chapter 17.4.3, Page 598:
In the TRY IT! section, the code should include an additional line as follows:
cmbxPhotographer.DataSource = _album;
cmbxPhotographer.DisplayMember = "Photographer";
cmbxPhotographer.DataBindings.Add("Text", _album, "Photographer");
The final line here ensures that the current photographer is properly displayed for each photograph in the Photos tab. Note that the text uses a 'DataMember' property, which does not exist. The code here using the DisplayMember property is correct.
Section 18.1.1, Page 605:
In step 1, the text says to assign the MergeOrder of the menu separator to 6, which does not produce the desired result. To fix this, do the following:
Section 18.2.1, Page 613:
In step 3, the Text property for the Label control should be "&Interval:" (with the colon).
Section 18.4.2, Page 630:
In step 4, it says there are two assemblies and "These are:" but gives the command again rather than the assembly names. The assemblies generated are:
c:\Windows Forms\Projects\WebBrowserSHDocVw.dll
c:\Windows Forms\Projects\WebBrowserAxSHDocVw.dll
Section 18.4.3, Page 631-632:
In step 4, the third line of the long string for the dlg.AboutText
setting contains the text "\nSample for /"Windows Forms ." The
second slash should escape the quote. The correct line is:
"\nSample for \"Windows Forms "
Also, in step 6, the word "assemply" should be "assembly"
Figure C.6, Page 687 (and back cover):
The PrintPreviewControl class shown here should be PrintPreviewDialog. The PrintPreviewControl class is based on the Control class (shown on the prior page), while the PrintPreviewDialog class is based on the Form class.