Online Help

Introduction

Online help is the system of providing help files with an application. Online help is usually available from the main menu through a menu group created under a Help category.

In the past, the techniques to provide or program online help were not always easy. The early implementations of help were created in a system called WinHelp. This required using a Rich Text Format (rtf) file and appropriately formatting it. It is possible that, when folks at Microsoft developed WinHelp, they had only Microsoft Word in mind. It was difficult to get the required file ready if you were using another application such as WordPad or WordPerfect. Creating the help file was not enough. Once the file was ready, it had to be added to the application, and appropriately. This back and forth gymnastic could result in negligence.

Practical LearningPractical Learning: Introducing Online Help

  1. In your computer, create a folder named College Park Auto-Parts. If you are using Microsoft Windows, create that folder in your C:\ drive
  2. Save the following image in that folder:

    College Park Auto-Parts

  3. Save the following icons to a folder on your computer or to the College Park Auto-Parts folder:
    Icon - House Icon - House Icon - Plus Icon - Minus Icon - Clipper
    Icon - Clipping Icon - Car Red Icon - Car Blue Icon - Tool Icon - Accessory
  4. Start Microsoft Visual Studio
  5. Create a new Windows Forms App named AutoPartsInventory5 that supports .NET 8.0 (Long-Term Support)
  6. In the Solution Explorer, right-click the name of the project and click Manage NuGet Packages...
  7. In the NuGet tab, click Browse
  8. In the combo box, type VisualBasic
  9. In the list, click Microsoft.VisualBasic
  10. In the right list, click Install
  11. In the Preview Changes dialog box, click Apply
  12. In the Solution Explorer, right-click the name of the project -> Add -> New Folder
  13. For the name of the folder, type Models
  14. In the Solution Explorer, right-click Models -> Add -> Class...
  15. For the name of the class, type AutoPart
  16. Click Add
  17. Change the document as follows:
    namespace AutoPartsInventory5.Models
    {
        internal class AutoPart
        {
            internal long    PartNumber    { get; set; }
            internal int     Year          { get; set; }
            internal string? Make          { get; set; }
            internal string? Model         { get; set; }
            internal string? Category      { get; set; }
            internal string? PartName      { get; set; }
            internal string? PartImage     { get; set; }
            internal double  UnitPrice     { get; set; }
            internal string? PictureNumber { get; set; }
        }
    }
  18. In the Solution Explorer, right-click Models -> Add -> Class...
  19. For the name of the class, type Repository
  20. Click Add
  21. Change the document as follows:
    using Microsoft.VisualBasic;
    
    namespace AutoPartsInventory5.Models
    {
        internal static class Repository
        {
            public static Collection AutoParts { get; set; } = new Collection(); 
        }
    }
  22. To start a new form, in the Solution Explorer, right-click the AutoPartsInventory5 project node -> Add -> Form (Windows Forms)...
  23. Set the name to Make
  24. Click Add
  25. Design the form as follows:

    College Park Auto-Parts - Make

    Control Text Name Other Properties
    Label Label &Make:    
    TextBox Text Box   txtMake Modifiers: Internal
    Button Button &Help btnHelp  
    Button Button &OK btnOK DialogResult: OK
    Button Button &Cancel btnCancel DialogResult: Cancel
  26. To create a new form, on the main menu, click Project -> Add Form (Windows Forms)...
  27. Set the name to Model
  28. Click Add
  29. Design the form as follows:

    College Park Auto Parts: Model

    Control Text Name Other Properties
    Label Label &Model:    
    TextBox Text Box   txtModel Modifiers: Internal
    Button Button &Help btnHelp  
    Button Button &OK btnOK DialogResult: OK
    Button Button &Cancel btnCancel DialogResult: Cancel
  30. To create a form, in the Solution Explorer, right-click AutoPartsInventory2 -> Add -> Form (Windows Forms)...
  31. Set the name to Category
  32. Click Add
  33. Design the form as follows:

    College Park Auto Parts: Category

    Control Text Name Other Properties
    Label Label &Category:    
    TextBox Text Box   txtCategory Modifiers: Internal
    Button Button &Help btnHelp  
    Button Button &OK btnOK DialogResult: OK
    Button Button &Cancel btnCancel DialogResult: Cancel
  34. On the main menu, click Project -> Add Form (Windows Forms)...
  35. In the middle list of the Add New Item dialog box, click About Box (Windows Forms)
  36. Set the Name to AboutNewAutoPart
  37. Click Add
  38. Change the values in the form as follows:
    Product Name: New Auto Part
    Version: 1.0.0.5
    Copyright: © 2001-2025
    Company Name: College Park Auto-Parts
    Description: The New Auto Part form is used to create a new store item to be added to the application.
  39. On the main menu, click Project -> Add Form (Windows Forms)...
  40. Set the Name to AutoPartNew
  41. Click Add
  42. On the Toolbox, click Menus & Toolbars
  43. Still in the Toolbox, click MenuStrip
  44. Click the form
  45. On the form, click Type Here. Type &File
  46. Below File, in the Type Here text box, type New &Make...
  47. Below Make, click Type Here, type New M&odel...
  48. Below Model, click Type Here, type New C&ategory...
  49. Below Category, click Type Here, type -
  50. Below the line, click Type Here, type Sa&ve Auto Part
  51. Below Save Auto Part, click Type Here, type -
  52. Below the line, click Type Here, type &Close

    College Park Auto-Parts - New Auto Part

  53. On the right side of File, click Type Here, type &Help Enter
  54. Below Help, click Type Here, type &Presentation
  55. Below Search..., click Type Here, type -
  56. Below the line, click Type Here, type &About New Auto Part...

    College Park Auto-Parts - New Auto Part

  57. In the Properties window, change the following characteristics of the menu items:
    Menu Text (Name) ShortcutKey
    &File miFile  
    New &Make... miFileNewMake Ctrl + Shift + M
    New M&odel... miFileNewModel Ctrl + Shift + O
    New C&ategory... miFileNewCategory Ctrl + Shift + G
    Sa&ve Auto Part miFileSaveAutoPart Ctrl + Shift + S
    &Close miFileClose Ctrl + Shift + X
    &Help miHelp  
    &Presentation... miPresentation F1
    &About New Auto Part... miHelpAboutNewAutoPart Ctrl + F12
  58. Design the form as follows:

    College Park Auto Parts - New Auto Part

    Control (Name) Text Additional Properties
    Label Label   &Part #:  
    TextBox Text Box txtPartNumber    
    Label Label lblPictureNumber ...  
    Picture Box Picture Box pbxPartImage   BorderStyle: FixedSingle
    SizeMode: AutoSize
    Label Label   &Year:  
    Combo Box Combo Box cbxYears   DropDownStyle: DropDownList
    Label Label   &Make:  
    Combo Box Combo Box cbxMakes   DropDownStyle: DropDownList
    Label Label   M&odel  
    Combo Box Combo Box cbxModels   DropDownStyle: DropDownList
    Label Label   Ca&tegory:  
    Combo Box Combo Box cbxCategories   DropDownStyle: DropDownList
    Label Label   Part Na&me:  
    Text Box Text Box txtPartName   ScrollBars: Vertical
    Multiline: True
    Label Label   &Unit Price:  
    Text Box Text Box txtUnitPrice   TextAlign: Right
    Label Label   ____________________  
    Status Strip Status Strip ssStatusBar   StatusLabel:
    Text: Guide
    (Name): slGuide
  59. On the main menu, click Project -> Add Form (Windows Forms)...
  60. In the middle list of the Add New Item dialog box, click About Box (Windows Forms)
  61. Set the Name to AboutCPAP
  62. Click Add
  63. Change the values in the form as follows:
    Product Name: Store Inventory
    Version: 1.0.0.5
    Copyright: © 2001-2025
    Company Name: College Park Auto-Parts
    Description: This version of the College Park Auto-Parts application 
    was created in Microsoft Visual Studio 2022 (the current version was 
    created around February-March 2024). The code is written in C#. Some 
    photos and other graphics were used to enhance the aesthetic aspects 
    of the application).
  64. In the Solution Explorer, right-click Form1.cs and click Rename
  65. Type StoreInventory (to have StoreInventory.cs) and press Enter three times to accept the name and display the form
  66. From the Components section of the Toolbox, click ImageList and click the form
  67. In the Properties window, click (Name) and type AutoPartsImages
  68. Click the ellipsis button of the Images field
  69. In the Image Collection Editor, click Add
  70. Select each of the icons that you had saved

    Collection Collection Editor

  71. Click OK
  72. On the Toolbox, click Menus & Toolbars and click MenuStrip
  73. Click the StoreInventory form
  74. On the form, click Type Here. Type &File and press Enter
  75. Below File, in the Type Here text box, type &New Auto Part... and press Enter
  76. Below &New Auto Part..., click Type Here, type - and press Enter
  77. Below the line, click Type Here, type E&xit and press Enter
  78. On the right side of File, click Type Here, type &Help and press Enter
  79. Below Help, click Type Here, type &Contents... and press Enter
  80. Below Contents..., click Type Here, type &Index... and press Enter
  81. Below Index..., type &Search... and press Enter
  82. Below Search..., click Type Here, type - and press Enter
  83. Below the line, click Type Here, type &About College Park Auto-Parts... and press Enter
  84. In the Properties window, change the following characteristics of the menu items:
    Menu Text (Name) ShortcutKey
    &File miFile  
    &New Auto Part... miFileNewAutoPart Ctrl + N
    E&xit miFileExit Ctrl + X
    &Help miHelp  
    &Contents... miHelpContents F1
    &Index... miHelpIndex Ctrl + I
    &Search... miHelpSearch Ctrl + E
    &About New Auto Part... miHelpAboutCollegeParkAutoParts Ctrl + F4
  85. Design the form as follows:

    College Park Auto Parts - Form Design

    Control (Name) Text Other Properties
    Label Label   College Park Auto-Parts Font: Times New Roman, 20.25pt, style=Bold
    ForeColor: Blue
    Panel Panel     BackColor: Black
    Height: 2
    GroupBox Group Box   Part Identification  
    TreeView Tree View tvwAutoParts   ImageList: AutoPartsImages
    GroupBox Group Box   Available Parts  
    ListView List View lvwAutoParts   FullRowSelect: True
    GridLines: True
    View: Details
    Columns   (Name) Text TextAlign Width
    colAvailablePartNumber Part #    
    colAvailablePartName Part Name/Description   300
    colAvailableUnitPrice Unit Price Right 80
    GroupBox Group Box   Selected Parts  
    Label Label   Part #  
    Label Label   Part Name  
    Label Label   Unit Price  
    Label Label   Qty  
    Label Label   Sub Total  
    TextBox Text Box txtPartNumber    
    TextBox Text Box txtPartName    
    TextBox Text Box txtUnitPrice   TextAlign: Right
    TextBox Text Box txtQuantity   TextAlign: Right
    TextBox Text Box txtSubTotal   TextAlign: Right
    Button Button btnAdd Add/Select  
    ListView List View lvwSelectedParts   FullRowSelect: True
    GridLines: True
    View: Details
    Columns   (Name) Text TextAlign Width
    colSelectedPartNumber Part #   45
    colSelectedPartName Part Name/Description   274
    colSelectedUnitPrice Unit Price Right 58
    colSelectedQuantity Qty Right 28
    colSelectedSubTotal Sub-Total Right 58
    GroupBox Group Box Order Summary    
    Label Label   Selected Parts Total:  
    TextBox Text Box txtSelectedPartsTotal 0.00 TextAlign: Right
    Label Label Tax Rate:    
    TextBox Text Box txtTaxRate 7.75 TextAlign: Right
    Label Label   %  
    Label Label   Tax Amount:  
    TextBox Text Box txtTaxAmount   TextAlign: Right
    Label Label   Order Total:  
    TextBox Text Box txtOrderTotal 0.00 TextAlign: Right
    Status Strip Status Strip ssStatusBar    

Context-Sensitive Help

Context-sensitive help allows the user to get local help on a particular control. You, as the application creator, will decide how you want context-sensitive help to work. In the past, you could make it so that if the user clicked a control and then press Shift+F1, the control that had focus would display a yellow box with a word:

Microsoft Access - Context-Sensitive Help

You also make the yellow box appear with many words:You can still do that but the means to do it have changed. Another technique works only on a dialog. It consists of adding a button with a question mark and then creating the words that would display eventually. When you create this type of dialog box, the user can click the question marked button and click a control. The user can also press Shift+F1. This causes the mouse pointer to be equipped with a question mark. The user can then click a control and a yellow box would appear for that control, providing help:

Help

Context-sensitive help is done in a few steps. To start, to support context-sensitive help, the Form class is equipped with a Boolean property named HelpButton:

public bool HelpButton { get; set; }

If you set this property to true or True, its form is supposed to display a button with a question mark. In reality, you must change the form into a dialog box, which is done by setting both the MaximizeBox and the MinimizeBox properties to true or True.

The Help Provider

To make it easy to provide online help in a Windows Forms application, the .NET Framework provides a control named HelpProvider that is based on a class of the same name:

public class HelpProvider : System.ComponentModel.Component, System.ComponentModel.IExtenderProvider

As is the case for other classes, you can declare a variable of this class and initiaze it. This can be done as follows:

namespace AutoPartsInventory5
{
    public partial class AutoPartNew : Form
    {
        HelpProvider HelpProvider;

        public AutoPartNew()
        {
            InitializeComponent();
        }

        private void AutoPartNew_Load(object sender, EventArgs e)
        {
            HelpProvider = new HelpProvider();
        }
    }
}

To visually provide this controk to your application, in the Components section of the Toolbox, click HelpProvider and click your form. After adding this control to a form, the form and all controls on it receive a new property labeled HelpString On HelpProvider_X. You can then type the desired string in the field of the Properties window for each control that would display context-sensitive help.

Practical LearningPractical Learning: Providing Help

  1. Click the Make.cs [Design] tab to access its form
  2. In the Components section of the Toolbox, click HelpProvider and click the form
  3. In the Properties window, change the (Name) to hpCPAP
  4. Click an unoccupied area of the form to make sure no Windows control is selected
  5. In the Properties window of the form, change the following characteristics:
    Form Property Value
    FormBorderStyle FixedDialog
    Text College Park Auto-Parts - Make
    StartPosition CenterScreen
    AcceptButton btnOK
    CancelButton btnCancel
    HelpButton True
    MaximizeBox False
    MinimizeBox False
    ShowInTaskbar False
  6. On the form, click the text box and buttons, and change the following charactereristics
  7. In the Properties window, change the following characteristics:
    Control HelpString On hpCPAP PlaceholderText
    Make Text Box Type the name of a vehicle manufacturer (domestic or international) Manufacturer
    Help Access manufacturer-related help  
    OK In the Make text box, type a vehicle manufacturer and click OK  
    Canel Click to dismiss any change  
  8. Below the form, click hpCPAP to select it and press Ctrl + C to copy
  9. Click the Model.cs [Design] tab to access its form
  10. Press Ctrl + V to paste the help provider
  11. Click an unoccupied area of the form to make sure no Windows control is selected
  12. In the Properties window of the form, change the following characteristics:
    Form Property Value
    FormBorderStyle FixedDialog
    Text College Park Auto-Parts - Model
    StartPosition CenterScreen
    AcceptButton btnOK
    CancelButton btnCancel
    HelpButton True
    MaximizeBox False
    MinimizeBox False
    ShowInTaskbar False
  13. On the Model form, click the text box and buttons, and change the following charactereristics
  14. In the Properties window, change the following characteristics:
    Control HelpString On hpCPAP PlaceholderText
    Model Text Box Common name of vehicle model, with optional characteristics Known Vehicle Model
    Help Access model-related help  
    OK In the Model text box, type the model set by the vehicle manufacturer. You can also provide more details specific to the model. Then click OK  
    Cancel Click to dismiss any change  
  15. Below the form, click hpCPAP to select it and press Ctrl + C to copy
  16. Click the Category.cs [Design] tab to access its form
  17. Press Ctrl + V to paste the help provider
  18. Click an unoccupied area of the form to make sure no Windows control is selected
  19. In the Properties window of the form, change the following characteristics:
    Form Property Value
    FormBorderStyle FixedDialog
    Text College Park Auto-Parts - Category
    StartPosition CenterScreen
    AcceptButton btnOK
    CancelButton btnCancel
    HelpButton True
    MaximizeBox False
    MinimizeBox False
    ShowInTaskbar False
  20. On the Category form, click the text box and buttons, and change the following charactereristics
  21. In the Properties window, change the following characteristics:
    Control HelpString On hpCPAP PlaceholderText
    Category Text Box Common or easily recognizable classification of an auto part (can include main or sub-categories of a part). Classification of a Store Item
    Help Access category-related help  
    OK In the Category text box, enter a few word that reoresent (or can briefly describe) the type of item. Then click OK  
    Cancel Click to dismiss any change  
  22. Below the form, click hpCPAP to select it and press Ctrl + C to copy
  23. Click the AutoPartNew.cs [Design] tab to access its form
  24. Press Ctrl + V to paste the help provider
  25. Click an unoccupied area of the form to make sure no Windows control is selected
  26. In the Properties window of the form, change the following characteristics:
    Form Property Value
    Text College Park Auto-Parts - New Auto-Part
    StartPosition CenterScreen
    HelpButton True
    MaximizeBox False
    MinimizeBox False
    ShowInTaskbar False
  27. On the New Auto-Part form, click some controls and, in the Properties window, change the following charactereristics:
    Control HelpString On hpCPAP PlaceholderText
    Part # Text Box The part number is required. This number must be unique among the other part numbers of the inventory (every auto-part must have a unique part number). Unique Part Number
    Picture Box A picture box shows a photo of the auto-part.  
    Years Combo Box Vehicle Year: This is the official year the car was released by the manufacturer (not the year the part was made)  
    Makes Combo box The vehicle manufacturer, commonly referred to as Make.  
    Models Combo box The model of the vehicle. The commonly-known name is from the manufacturer. The model can also include a short description and/or characteristics that make it easy to locate an auto-part.  
    Category Combo Box Part Category: This is a name (or a relatively short description) of the type of part.  
    Part Name Text Box The name of the auto-part: The name can consist of a few words or a relatively short description with enough information to provide all necessary details.  
    Unit Price Text Box This is the current marked price of the auto-part. It doesn't reflect a discount nor a tax amount. Part Price

HTML Help

Introduction

The online help we described earlier provides only small yellow boxes. It is called context-sensitive help because it provides its assistance on only a control of the form. Another technique, in fact highly supported with any commercial program, consists of providing an external application that resembles an electronic book. This allows the user to get more detailed information about almost any aspect of the application.

The most common way to provide online help is by using a Web site. You can create a local Web site that resides on your computer; that website is accessed only by the computer where the site resides. You can also create a Website that is accessed in the Internet.

Practical LearningPractical Learning: Creating HTML Help Files

  1. Using Windows Explorer or My Computer, create a folder named cpap
  2. Inside of the cic folder, create a folder named images
  3. Inside of the cic folder, create another folder named styles
  4. Save the following images in the cpap\images folder:

    College Park Auto-Parts - Accessories

    College Park Auto-Parts - New Auto Part

    College Park Auto-Parts

    College Park Auto-Parts - Accessories College Park Auto-Parts - Accessories
    College Park Auto-Parts - Parts College Park Auto-Parts - Make
    College Park Auto-Parts - Model College Park Auto-Parts - Category
    College Park Auto-Parts College Park Auto-Parts
    College Park Auto-Parts College Park Auto-Parts
    College Park Auto-Parts
  5. Start a text editor, such as Notepad, and paste the content of the cpap.css file in it
  6. Save the file as cpap.css in the styles folder you created
  7. Start another file with the contents of the Accessies document
  8. Save the file as Accessories.htm
  9. Start another file with the contents of the Description document
  10. Save the file as Description.htm
  11. Start another file with the contents of the New Auto Part document
  12. Save the file as NewAutoPart.htm
  13. Start another file with the contents of the Introduction document
  14. Save it as Introduction.htm
  15. Start another file with the contents of the Make document
  16. Save the file as Make.htm
  17. Start another file with the contents of the Model document
  18. Save the file as Model.htm
  19. Start another file with the contents of the Category document
  20. Save the file as Category.htm
  21. Start another file with the contents of the Index document
  22. Save it as index.htm

Introduction to HTML Help

When it comes to online help, a solution that Microsoft made available in the past was called HTML Help. It was an external applicatton that was used to gather existing Web files and make them into an executable application. This means that you had to first create all the files you would need for a website. Once you had the Web files you wanted, you had to start the HTML Help application, create a project, import the necessary files, and make the whole combination into a functioning system. At any time, you could compile the project to create an executable application, which had a .chm extension.

Practical LearningPractical Learning: Introducing HTML Help

  1. If you haven't done so, install HTML Help or www.helpandmanual.com/downloads_mscomp.html or web.archive.org/web/20210126113408/https://www.microsoft.com/en-us/download/details.aspx?id=21138
    Start HTML Help Workshop

    HTML Help Workshop

  2. On the main menu of HTML Help Workshop, click File -> New

    HTML Help Workshop - New

  3. In the New dialog box, make sure Project is selected and click OK

    New Project Wizard - First Page

  4. In the first page of the New Project wizard, click Next

    New Project - Destination

  5. In the second page of the wizard, click Browse
  6. Locate the cpap folder you created and display its contents
  7. Set the File Name to College Park Auto-Parts

    The Open Dialog Box

  8. Click Open

    New Project - Destination

  9. In the second page, click Next
  10. In the third page, read the text. Click the HTML files (.htm) check box:

    New Project - Existing Files

  11. Click Next
  12. In the fourth page, click Add
  13. In the Open dialog box, click the top Web file
  14. Press and hold Shift
  15. Click the last Web file to select them all
  16. Release Shift:

    The Open Dialog Box - Selecting the HTML files

  17. Click Open:

  18. In the fourth page, click Next
  19. In the last page of the wizard, click Finish:

    HTML Help Workshop

  20. To create the help file, click the Save All Files And Compile button

    HTML Help Workshop

  21. Inside the HTML Help Worskop, close the window titled Log1
    If you want, access the cpap folder and double-click the College Park Auto-Parts.chm executable to see the application

    HTML Help Workshop

    If you had opened that Help application, close it

A Window to Display Help

An HTML Help application primarily appears as a single document or a Web page. In reality, most help systems use many Web files. If you want to display the various HTML files that your system offers, the HTML Help Workshop suggests that you create one or more special windows from which the user can navigate from one Web page to another.

To create a window to display Help, in the Projects tab, you can click the Add/Modify Window Definitions Add/Modify Window Definitions button. Because you are allowed to have many Help windows, to start, you must provide a name for your new window. You can then specify its characteristics, and then modify them later as you wish.

Practical LearningPractical Learning: Creating a Help Window

  1. Click the Add/Modify Window Definitions button Add/Modify Window Definitions
  2. Set the name to MainWnd

    HTML Help Workshop

  3. Press Enter
  4. Set the Title Bar Text to College Park Auto-Parts

    Window Types

  5. Click the Buttons tab
  6. Click the Home and the Locate check boxes

    Window Types - Buttons

  7. Click the Position tab
  8. Set the Width to 1920
  9. Set the Height to 1080

  10. Click the Files tab
  11. Click the arrow of the Default combo box and select index.htm
  12. Click the arrow of the Home combo box and select Introduction
  13. Click OK
  14. To create the help file, click the Save All Files And Compile button
  15. Inside the HTML Help Worskop, close the window titled Log1
    If you want, access the cpap folder and double-click the College Park Auto-Parts.chm executable to see the application.

    HTML Help Workshop

    If you had opened that Help application, close it

A Table of Contents

To provide the functionality of an electronic book, you can equip your HTML Help application with a Table of Contents section. To start, in your HTML Help Workshop application, create a Table of Contents from the Contents tab.

To support the Table of Contents of HTML Help, the HelpNavigator enumeration has a member named TableOfContents.

Practical LearningPractical Learning: Creating a Table of Contents

  1. In the HTML Help Workshop, click the Contents tab
    In the dialog box that displays, read the text in the dialog box. Make sure the first radio button is selected:

  2. Click OK
  3. In the Save As dialog box, accept the suggested name:

    Save As

  4. Click Save
  5. Click the Insert a Heading button Insert a Heading
  6. In the Table Of Contents Entry dialog box, in the Entry Title text box, type College Park Auto-Parts
  7. Click Add
  8. In the Path Or URL dialog box, click College Park Auto-Parts - Home

    Path or URL

  9. Click OK

    Table of Contents Entry

  10. Click OK
  11. Click the Insert A Page button Insert A Page

    HTML Help Workshtop

  12. In the message box that displays, read it and click No
  13. In the Entry Title text box, type Introduction
  14. Click Add
  15. In the Path Or URL dialog box, click Introduction

    Path or URL

  16. Click OK
  17. In the Table Of Contents Entry dialog box, click OK
  18. Click the Insert A Page button Insert A Page
  19. In the Entry Title text box, type Description
  20. Click Add
  21. In the Path Or URL dialog box, click Description
  22. Click OK
  23. In the Table Of Contents Entry dialog box, click OK
  24. Click the Project tab
  25. In the list box, below [WINDOWS], double-click MainWnd = "College Park Autp-Parts"
  26. In the Window Types dialog box, click the Files tab
  27. Click the arrow of the TOC combo box and select Table of Contents.hhc
  28. Click OK
  29. To create the help file, click the Save All Files And Compile button
  30. Inside the HTML Help Worskop, close the window titled Log2
    If you want, access the cpap folder and double-click the College Park Auto-Parts.chm executable to see the application.
    If you had opened that Help application, close it

Help Index

When it comes to a book, an index is a list of special or difficult words for which a reader may need clarifying information. To make your Help project very userful, the HTML Help Workshop allows you to create an index for your Help system.

To create an index, in the HTML Help Workshop, click the Index tab,

Practical LearningPractical Learning: Creating an Index

  1. In the HTML Help Workshop, click the Index tab. Read the content of the dialog box that comes up.
    Make sure the top radio button is selected

    HTML Help

  2. Click OK
  3. Accept the suggested name of the file and press Enter
  4. Click the Insert A Keyword Insert A Keyword button
  5. In the Keyword text box, type domestic
  6. Click Add
  7. In the Path Or URL dialog box, click Introduction
  8. Click OK
  9. In the Index Entry dialog box, click OK
  10. Once again, click the Insert A Keyword Insert A Keyword
  11. You will receive a message box, click one of the buttons Yes or No (it doesn't matter which one)
  12. In the Keyword text box, type tree view
  13. Click the Add or the Edit button (it doesn't matter which one)
  14. In the HTML Titles list box, click Description
  15. At the end of the string in the File or URL text box, add #cpap

    Path or URL

  16. Click OK
  17. In the Index Entry dialog box, click OK
  18. In the same way, create new keywords using the following table (sometimes you may receive a message box asking whether you want to create the keyword above the other; for this exercise, it doesn't matter what Yes or No button you click):
    New Keyword Page or URL
    appearance Accessories
    accessories Accessories
    security Accessories
    environment Accessories
    warranty Introduction
    company Introduction
    text box Description.htm#cpap
    record Description.htm#cpap
  19. Click the Sort Keywords Alphabetically button

  20. Click the Project tab
  21. In the list box, below [WINDOWS], double-click MainWnd = "College Park Autp-Parts"
  22. Click Navigation Pane
  23. Click the Window With Navigation Pane, Topic Pane, And Button check box
  24. Click the Search Tab and the Advanced check boxes

  25. Click the Files tab
  26. Click the arrow of the Index combo box and select Index.hhk

  27. Click OK
  28. When the Resolve Window Definition wizard comes up, in the Window Type combo box, make sure the window defined previously is selected.
    Click Next
  29. Click Next
  30. Click Finish
  31. To create the help file, click the Save All Files And Compile button
  32. Inside the HTML Help Worskop, close the window titled LogX.
    Access the cpap folder and double-click the College Park Auto-Parts.chm executable to see the application

    HTML Help Workshop

  33. Expand the College Park Auto-Parts node and click Description

    HTML Help Workshop

    If you had opened that Help application, close it
  34. Click the Index tab

    HTML Help Workshop

  35. Close the Help application and return to your HTML Help Workshop project

Context-Sensitive Pop-up Help

When using your application, the user may open different objects and use some Windows controls. Context-sensitive help is help that applies to a particular object on an application.

Creating or implementing context-sensitive help can involve a few steps so much that it is an option you can avoid in your application (or you can create it if you judge it necessary (and/or helpful)).

The primary object involved with context-sensitive help is a header file. A header file is a C/C++ text fix that has the extention.h. In the document, you create what are called help topics or topic IDs. You can create one or more of such topics. The formula to create a topic ID is:

#define identifier natural-number

The line starts with #define followed by an empty space. This is followed by a name. By tradition, you should (maybe must) start that name with IDH_ followed by one or more digits and leters of your choice. You can also use one or more underscores. By tradition also, the whole name is in uppercase (this is not a requirement). After that name, create an empty space. Add a natural number. If you want to create another topic ID, do it on the next line. In the same way, you can create as many topic IDs as you want. If you are creating more than one topic ID, it is a good idea for each number to be unique.

If you started the document in a text editor such as Notepad, make sure you save it with the .h extension in your HTML Help project folder. After creating the header file, you must import it in your HEML Help project. You must also create a section named ALIAS included in square brackets. Below its line, create an entry for each topic ID. The formula for each topic ID is:

identifier = associated-file

Start the line with an identifier you had created in the header file. Assign a name of a file to the identifier. This is the name of the file that will be associated to the topic ID. After doing this, you should (must) add the

Practical LearningPractical Learning: Creating a Header File

  1. Start a text editor such as Notepad
  2. Type the following lines:
    #define IDH_MAKE	  1000
    #define IDH_MODEL	  1010
    #define IDH_CATEGORY	  1020
    #define IDH_NEW_AUTO_PART 1040
  3. Save the file as cpap.h in the cpap folder of your HTML Help project
  4. Return to the HTML Help Workshop.
    Click the HtmlHelp API information button
  5. In the HtmlHelp API Information dialog box, click Header File
  6. In the Include File dialog box, click Browse...
  7. Select the cpap.h file from your HTML Help project folder
  8. Click Open
  9. In the Include File dialog box, click OK

    HTML Help Worksheop - HtmlHelp API Information

  10. In the HtmlHelp API Information dialog box, click OK
  11. To save, click the Save All Files And Compile button
  12. Inside the HTML Help Worskop, close the window titled Log3
  13. Return to your HTML Help project folder.
    Right-click the College Park Auto-Parts.hhp file and choose the option to open it in a text file
  14. In the document, create an ALIAS section follows:
    [OPTIONS]
    Compatibility=1.1 or later
    Compiled file=College Park Auto-Parts.chm
    Default Window=MainWnd
    Default topic=Accessories.htm
    Display compile progress=No
    Language=0x409 English (United States)
    
    [WINDOWS]
    MainWnd="College Park Auto-Parts",,,"index.htm","Introduction.htm",,,,,0x2000,,0x3846,[0,0,1920,1080],,,,,,,0
    
    
    [FILES]
    Accessories.htm
    Category.htm
    Description.htm
    index.htm
    Introduction.htm
    Make.htm
    Model.htm
    NewAutoPart.htm
    
    [ALIAS]
    IDH_CATEGORY=Category.htm
    IDH_MAKE=Make.htm
    IDH_MODEL=Model.htm
    IDH_NEW_AUTO_PART=NewAutoPart.htm
    
    [MAP]
    #include cpap.h
    
    [INFOTYPES]
  15. Close the file
  16. When asked whether you want to save the file, press Enter (or click OK or Yes)

An HTML Provider

Introduction

After creating the HTML Help application, you can use a HelpProvider control to connect it to your application. To start, the HelpProvider class is equipped with a property called HelpNamespace:

public virtual string? HelpNamespace { get; set; }

This property allows you to specify the application that contains the HTML Help application. You can do this by assigning the name or path of your CHM application. Here is an example:

namespace AutoPartsInventory5
{
    public partial class AutoPartNew : Form
    {
        HelpProvider HelpProvider;

        public AutoPartNew()
        {
            InitializeComponent();
        }

        private void AutoPartNew_Load(object sender, EventArgs e)
        {
            HelpProvider = new HelpProvider();

            HelpProvider.HelpNamespace = "C:\\cpap\\College Park Auto-Parts.chm";
        }
    }
}

Besides the HelpNamespace property, the HelpProvider control provides various methods to manage help.

To support HTML Help for a Windows Forms Application, the .NET Framework provides a static class named Help:

public static class Help

Help is a small class that has only three methods, no constructors, and no properties. One of the methods of the Help class is named ShowHelp. It is overloaded in four versions. The simplest version uses the following syntax:

public static void ShowHelp(System.Windows.Forms.Control? parent, string? url);

This version of the ShowHelp() method allows you to specify the help file aplied to a control. The control is passed as the first argument. That control is usually a form. If you call this method on the form that needs the HTML Help file, you can pass the first argument as the this object. The second argument is the help file specified in the HelpProvider.HelpNamespace property already mentioned.

A Table of Contents

An HTML Help application usually displays various tabs. To display the Contents tab of HTML Help, simply call the Help.ShowHelp() method that uses the above syntax. Here is an example:

namespace AutoPartsInventory5
{
    public partial class AutoPartNew : Form
    {
        HelpProvider ? hpAutoParts;

        public AutoPartNew()
        {
            InitializeComponent();
        }

        private void AutoPartNew_Load(object sender, EventArgs e)
        {
            hpAutoParts = new HelpProvider();

            hpAutoParts.HelpNamespace = "C:\\cpap\\College Park Auto-Parts.chm";
        }

        private void miHelpContents_Click(object sender, EventArgs e)
        {
            Help.ShowHelp(this, "C:\\cpap\\College Park Auto-Parts.chm");
        }
    }
}

An Index for HTML Help

To let you access the Index tab of HTML Help, the Help class is equipped with a method named ShowHelpIndex method can be used to open the Index tab of the HTML Help window.

public static void ShowHelpIndex(System.Windows.Forms.Control? parent, string? url);

This method takes two arguments. The first argument is the control that needs the Helps project. Normally, this is a form and it is usually passed as this. The second argument is the CHM file of your HTML Help project. Here is an example of calling this method:

namespace ÂutoPartsInventory1
{
    public partial class StoreInventory : Form
    {
        HelpProvider? hpAutoParts;

        public StoreInventory()
        {
            InitializeComponent();
        }

        private void StoreInventory_Load(object sender, EventArgs e)
        {
            hpAutoParts = new HelpProvider();
            hpAutoParts.HelpNamespace = "C:\\cpap\\College Park Auto-Parts.chm";
        }

        private void miHelpContents_Click(object sender, EventArgs e)
        {
            Help.ShowHelpIndex(this, hpAutoParts!.HelpNamespace);
        }
    }
}

To support the tabs of HTML Help, the .NET Framework provides an enumeration named HelpNavigator.

Based on this, the second and the fourth versions of the ShowHelp() method allow you to specify the tab of the HTML Help window to display when the method is called. This is done through the HelpNavigator enumeration. To let you specify a tab, the Help.ShowHelpIndex() method has another version whose syntax is:

public static void ShowHelp(System.Windows.Forms.Control? parent,
                            string? url,
                            System.Windows.Forms.HelpNavigator navigator);

Using another solution to display the Contents tab of an HTML Help application, the HelpNavigator enumeration has a member named TableOfContents. To display the Contents tab of an HTML Help application, you can pass this member as the third argument. Here is an example:

namespace ÂutoPartsInventory1
{
    public partial class StoreInventory : Form
    {
        HelpProvider? hpAutoParts;

        public StoreInventory()
        {
            InitializeComponent();
        }

        private void StoreInventory_Load(object sender, EventArgs e)
        {
            hpAutoParts = new HelpProvider();
            hpAutoParts.HelpNamespace = "C:\\cpap\\College Park Auto-Parts.chm";
        }

        private void miHelpContents_Click(object sender, EventArgs e)
        {
            Help.ShowHelp(this, hpAutoParts!.HelpNamespace, HelpNavigator.TableOfContents);
        }
    }
}

Finding Help

The third version of the ShowHelp() method can be used to open a help file based on a keyword.

Practical LearningPractical Learning: Providing Online Help to an Application

  1. Click the Make.cs [Design] tab to access its form
  2. Below the Make form, click hpCPAP to access it
  3. In the Properties window, click the ellipsis button of the HelpNamespace property
  4. Locate and display the cpap folder in which you created the HTML Help project. Select the College Park Auto-Parts.chm file
  5. Click Open
  6. In the Make form, double-click the Help button to generate its Click event
  7. Implement the event as follows:
    namespace AutoPartsInventory5
    {
        public partial class Make : Form
        {
            public Make()
            {
                InitializeComponent();
            }
    
            private void btnHelp_Click(object sender, EventArgs e)
            {
                Help.ShowHelp(this, hpCPAP.HelpNamespace, HelpNavigator.TopicId, "1000");
            }
        }
    }
  8. Click the Model.cs [Design] tab to access its form
  9. In the Make form, double-click the Help button to generate its Click event
  10. Change the event as follows:
    namespace AutoPartsInventory5
    {
        public partial class Model : Form
        {
            public Model()
            {
                InitializeComponent();
            }
    
            private void btnHelp_Click(object sender, EventArgs e)
            {
                Help.ShowHelp(this, hpCPAP.HelpNamespace, HelpNavigator.TopicId, "1010");
            }
        }
    }
  11. Click the Category.cs [Design] tab to access its form
  12. In the Make form, double-click the Help button
  13. Define the event as follows:
    namespace AutoPartsInventory5
    {
        public partial class Category : Form
        {
            public Category()
            {
                InitializeComponent();
            }
    
            private void btnHelp_Click(object sender, EventArgs e)
            {
                Help.ShowHelp(this, hpCPAP.HelpNamespace, HelpNavigator.TopicId, "1020");
            }
        }
    }
  14. Click the NewAutoPart.cs [Design] tab to access its form
  15. Double-click an unoccupied area of the form to generate its Load event
  16. Return to the NewAutoPart.cs form and, on the form, click the Part Number text box to give it focus
  17. In the Properties window, click the Events button Events
  18. In the Events section of the Properties window, double-click Leave
  19. Return to the NewAutoPart.cs form. In the menu in the top section, click File and double-click New Make
  20. Return to the NewAutoPart.cs form and double-click the Make combo box to generate its SelectedIndexChanged event
  21. Return to the NewAutoPart.cs form. In the menu in the top section, click File and double-click New M&odel...
  22. Return to the NewAutoPart.cs form. In the menu in the top section, click File and double-click New C&ategory...
  23. Return to the NewAutoPart.cs form. In the menu in the top section, click Help and double-click Presentation...
  24. Return to the NewAutoPart.cs form. In the menu in the top section, click Help and double-click About New Auto Part...
  25. Return to the NewAutoPart.cs form. In the menu in the top section, click File and double-click Sa&ve Auto-Part
  26. Return to the NewAutoPart.cs form. In the menu in the top section, click File and double-click Close
  27. Change the document as follows:
    using AutoPartsInventory5.Models;
    
    namespace AutoPartsInventory5
    {
        public partial class AutoPartNew : Form
        {
            public AutoPartNew()
            {
                InitializeComponent();
            }
    
            private void InitializeAutoParts()
            {
                for (int year = 2025; year >= 2000; year--)
                {
                    cbxYears.Items.Add(year);
                }
    
                if (Repository.AutoParts.Count > 0)
                {
                    Random rndNumber = new();
    
                    cbxMakes.Items.Clear();
                    cbxModels.Items.Clear();
                    cbxCategories.Items.Clear();
                    txtPartName.Text = string.Empty;
                    txtUnitPrice.Text = string.Empty;
                    txtPartNumber.Text = rndNumber.Next(100000, 999999).ToString();
    
                    foreach (AutoPart part in Repository.AutoParts)
                    {
                        if (!cbxMakes.Items.Contains(part.Make))
                        {
                            cbxMakes.Items.Add(part.Make!);
                        }
                    }
    
                    foreach (AutoPart part in Repository.AutoParts)
                    {
                        if (!cbxCategories.Items.Contains(part.Category))
                        {
                            cbxCategories.Items.Add(part.Category!);
                        }
                    }
                }
    
                lblPictureNumber.Text = ".";
                pbxPartImage.Image = Image.FromFile(@"E:\College Park Auto-Parts\Generic.png");
    
                Width = pbxPartImage.Right + 40;
                Height = pbxPartImage.Bottom + 75;
            }
    
            private void AutoPartNew_Load(object sender, EventArgs e)
            {
                InitializeAutoParts();
            }
    
            private void txtPartNumber_Leave(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(txtPartNumber.Text))
                {
                    return;
                }
    
                lblPictureNumber.Text = txtPartNumber.Text;
                pbxPartImage.Image = Image.FromFile(@"E:\College Park Auto-Parts\" + txtPartNumber.Text + ".png");
    
                Width = pbxPartImage.Right + 40;
                Height = pbxPartImage.Bottom + 75;
            }
    
            private void miFileNewMake_Click(object sender, EventArgs e)
            {
                Make editor = new Make();
    
                if (editor.ShowDialog() == DialogResult.OK)
                {
                    if (editor.txtMake.Text.Length > 0)
                    {
                        string strMake = editor.txtMake.Text;
    
                        if (cbxMakes.Items.Contains(strMake))
                        {
                            MessageBox.Show(strMake + " is already in the list.",
                                            "College Park Auto-Parts",
                                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                        else
                        {
                            cbxMakes.Items.Add(strMake);
                        }
    
                        cbxMakes.Text = strMake;
                    }
                }
            }
    
            private void cbxMakes_SelectedIndexChanged(object sender, EventArgs e)
            {
                cbxModels.Text = "";
                cbxModels.Items.Clear();
    
                foreach (AutoPart part in Repository.AutoParts)
                {
                    if (part.Make == cbxMakes.Text)
                    {
                        if (!cbxModels.Items.Contains(part.Model))
                        {
                            cbxModels.Items.Add(part.Model!);
                        }
                    }
                }
            }
    
            private void miFileNewModel_Click(object sender, EventArgs e)
            {
                Model editor = new();
    
                if (editor.ShowDialog() == DialogResult.OK)
                {
                    if (editor.txtModel.Text.Length > 0)
                    {
                        string strModel = editor.txtModel.Text;
    
                        if (cbxModels.Items.Contains(strModel))
                        {
                            MessageBox.Show(strModel + " is already in the list.",
                                            "College Park Auto-Parts",
                                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
    
                        else
                        {
                            cbxModels.Items.Add(strModel);
                        }
    
                        cbxModels.Text = strModel;
                    }
                }
            }
    
            private void miFileNewCategory_Click(object sender, EventArgs e)
            {
                var editor = new Category();
    
                if (editor.ShowDialog() == DialogResult.OK)
                {
                    if (editor.txtCategory.Text.Length > 0)
                    {
                        string strCategory = editor.txtCategory.Text;
    
                        if (cbxCategories.Items.Contains(strCategory))
                        {
                            MessageBox.Show(strCategory + " is already in the list.",
                                            "College Park Auto-Parts",
                                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
    
                        else
                        {
                            cbxCategories.Items.Add(strCategory);
                        }
    
                        cbxCategories.Text = strCategory;
                    }
                }
            }
    
            private void miPresentation_Click(object sender, EventArgs e)
            {
                Help.ShowHelp(this, hpCPAP.HelpNamespace, HelpNavigator.TopicId, "1040");
            }
    
            private void miHelpAboutNewAutoPart_Click(object sender, EventArgs e)
            {
                AboutNewAutoPart ana = new();
    
                ana.ShowDialog();
            }
    
            private void miFileSaveAutoPart_Click(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(cbxYears.Text))
                {
                    MessageBox.Show("You must specify the year.",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
    
                // Make sure the user had selected a make
                if (string.IsNullOrEmpty(cbxMakes.Text))
                {
                    MessageBox.Show("You must specify the car name.",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
    
                // Make sure the user had selected a model
                if (string.IsNullOrEmpty(cbxModels.Text))
                {
                    MessageBox.Show("You must specify the model of the car.",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
    
                // Make sure the user had entered a name/description
                if (string.IsNullOrEmpty(txtPartName.Text))
                {
                    MessageBox.Show("You must enter the name (or a " +
                                    "short description) for the part.",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                    txtPartName.Focus();
                    return;
                }
    
                // Make sure the user had typed a price for the item
                if (string.IsNullOrEmpty(txtUnitPrice.Text))
                {
                    MessageBox.Show("You must enter the price of the item.",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                    txtUnitPrice.Focus();
                    return;
                }
    
                AutoPart part = new AutoPart();
    
                part.PartNumber = long.Parse(txtPartNumber.Text);
                part.Year = int.Parse(cbxYears.Text);
                part.Make = cbxMakes.Text;
                part.Model = cbxModels.Text;
                part.Category = cbxCategories.Text;
                part.PartName = txtPartName.Text;
                part.UnitPrice = double.Parse(txtUnitPrice.Text);
                part.PictureNumber = lblPictureNumber.Text;
    
                Repository.AutoParts.Add(part);
    
                InitializeAutoParts();
            }
    
            private void miFileClose_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  28. Return to the NewAutoPart.cs form. Below the NewAutoPart form, click hpCPAP to select it and press Ctrl + C to copy
  29. Click the StoreInventory.cs [Design] tab to access its form
  30. Press Ctrl + V to paste the help provider
  31. Double-click an unoccupied area of the form to generate its load event
  32. Return to the StoreInventory.cs form and, in the Properties window, click the Events button Events
  33. On the form, click the Part Identification tree view
  34. In the Events section of the Properties window, double-click NodeMouseClick
  35. Return to the StoreInventory.cs form. In its top section, click File and double-click New Au&to Part...
  36. Return to the StoreInventory.cs form. On the form, click the Available Parts list view to select it and, in the Events section Properties window, double-click ItemSelectionChanged
  37. Return to the StoreInventory.cs form and make sure the Available Parts list view is still selected.
    In the Events section of the Properties, double-click DoubleClick
  38. Return to the StoreInventory.cs form and click the Part # text box to select it
  39. In the Events section of the Properties window, double-click Leave
  40. Return to the StoreInventory.cs form and click the Unit Price text box to select it
  41. In the Events section of the Properties window, double-click Leave
  42. Return to the StoreInventory.cs form and click the Qty text box to select it
  43. In the Events section of the Properties window, click the arrow of the Leave combo box and select txtUnitPrice_Leave
  44. Return to the StoreInventory.cs form and double-click the Add/Select
  45. Return to the StoreInventory.cs form and click the Selected Parts list view to select it
  46. In the Events section of the Properties window, double-click DoubleClick
  47. Return to the StoreInventory.cs form. In its top section, click Help and double-click Contents...
  48. Return to the StoreInventory.cs form. In its top section, click Help and double-click Index...
  49. Return to the StoreInventory.cs form. In its top section, click Help and double-click About... College Park Auto-Parts...
  50. Return to the StoreInventory.cs form. In its top section, click File and double-click Exit
  51. Change the document as follows:
    using AutoPartsInventory5.Models;
    using Microsoft.VisualBasic;
    
    namespace AutoPartsInventory5
    {
        public partial class StoreInventory : Form
        {
            public StoreInventory()
            {
                InitializeComponent();
            }
    
            void InitializeAutoParts()
            {
                tvwAutoParts.Nodes.Clear();
                TreeNode nodRoot = tvwAutoParts.Nodes.Add("College Park Auto-Parts",
                                                          "College Park Auto-Parts", 0, 1);
    
                for (int years = 2025; years >= 2000; years--)
                {
                    nodRoot.Nodes.Add(years.ToString(), years.ToString(), 2, 3);
                }
    
                tvwAutoParts.SelectedNode = nodRoot;
    
                tvwAutoParts.ExpandAll();
    
                if (Repository.AutoParts.Count > 0)
                {
                    foreach (TreeNode nodYear in nodRoot.Nodes)
                    {
                        Collection lstMakes = new();
    
                        foreach (AutoPart part in Repository.AutoParts)
                        {
                            if (nodYear.Text == part.Year.ToString())
                            {
                                if (!lstMakes.Contains(part.Make!))
                                {
                                    lstMakes.Add(part.Make!, part.Make!);
                                }
                            }
                        }
    
                        foreach (string strMake in lstMakes)
                        {
                            nodYear.Nodes.Add(strMake, strMake, 4, 5);
                        }
                    }
    
                    foreach (TreeNode nodYear in nodRoot.Nodes)
                    {
                        foreach (TreeNode nodMake in nodYear.Nodes)
                        {
                            Collection lstModels = new();
    
                            foreach (AutoPart part in Repository.AutoParts)
                            {
                                if ((nodYear.Text == part.Year.ToString()) &
                                    (nodMake.Text == part.Make))
                                {
                                    if (!lstModels.Contains(part.Model!))
                                    {
                                        lstModels.Add(part.Model!, part.Model!);
                                    }
                                }
                            }
    
                            foreach (string strModel in lstModels)
                            {
                                nodMake.Nodes.Add(strModel, strModel, 6, 7);
                            }
                        }
                    }
    
                    foreach (TreeNode nodYear in nodRoot.Nodes)
                    {
                        foreach (TreeNode nodMake in nodYear.Nodes)
                        {
                            foreach (TreeNode nodModel in nodMake.Nodes)
                            {
                                Collection lstCategories = new();
    
                                foreach (AutoPart part in Repository.AutoParts)
                                {
                                    if ((nodYear.Text == part.Year.ToString()) &
                                        (nodMake.Text == part.Make) &
                                        (nodModel.Text == part.Model))
                                    {
                                        if (!lstCategories.Contains(part.Category!))
                                        {
                                            lstCategories.Add(part.Category!, part.Category!);
                                        }
                                    }
                                }
    
                                foreach (string strCategory in lstCategories)
                                {
                                    nodModel.Nodes.Add(strCategory, strCategory, 8, 9);
                                }
                            }
                        }
                    }
                }
    
                lvwSelectedParts.Items.Clear();
                lvwAvailableParts.Items.Clear();
                txtPartName.Text = string.Empty;
                txtQuantity.Text = string.Empty;
                txtSubTotal.Text = string.Empty;
                txtUnitPrice.Text = string.Empty;
                txtTaxAmount.Text = string.Empty;
                txtOrderTotal.Text = string.Empty;
                txtPartNumber.Text = string.Empty;
                txtSelectedPartsTotal.Text = string.Empty;
                pbxPartImage.Image = Image.FromFile(@"E:\College Park Auto-Parts\Generic.png");
            }
    
            private void Form_Load(object sender, EventArgs e)
            {
                InitializeAutoParts();
            }
    
            void tvwAutoParts_NodeMouseClick(object o, TreeNodeMouseClickEventArgs e)
            {
                TreeNode nodClicked = e.Node;
    
                if (nodClicked.Level == 4)
                {
                    lvwAvailableParts.Items.Clear();
                }
    
                try
                {
                    foreach (AutoPart part in Repository.AutoParts)
                    {
                        if ((part.Category == nodClicked.Text) &&
                            (part.Model == nodClicked.Parent.Text) &&
                            (part.Make == nodClicked.Parent.Parent.Text) &&
                            (part.Year.ToString() == nodClicked.Parent.Parent.Parent.Text))
                        {
                            ListViewItem lviAutoPart = new ListViewItem(part.PartNumber.ToString());
    
                            lviAutoPart.SubItems.Add(part.PartName);
                            lviAutoPart.SubItems.Add(part.UnitPrice.ToString("F"));
                            lvwAvailableParts.Items.Add(lviAutoPart);
                        }
                    }
                }
                catch (NullReferenceException)
                {
                }
            }
    
            private void miFileNewAutoPart_Click(object sender, EventArgs e)
            {
                AutoPartNew apn = new();
    
                apn.ShowDialog();
    
                InitializeAutoParts();
            }
    
            private void lvwAvailableParts_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
            {
                bool pictureFound = false;
    
                if (Repository.AutoParts.Count > 0)
                {
                    foreach (AutoPart part in Repository.AutoParts)
                    {
                        if (part.PartNumber == long.Parse(e.Item!.SubItems[0].Text))
                        {
                            pictureFound = true;
                            pbxPartImage.Image = Image.FromFile(@"E:\College Park Auto-Parts\" + part.PictureNumber! + ".png");
                            break;
                        }
                    }
                }
    
                if (pictureFound == false)
                {
                    pbxPartImage.Image = Image.FromFile(@"E:\College Park Auto-Parts\Generic.png");
                }
    
                Width = pbxPartImage.Right + 40;
                Height = pbxPartImage.Bottom + 75;
            }
    
            private void lvwAvailableParts_DoubleClick(object sender, EventArgs e)
            {
                ListViewItem lviAutoPart = lvwAvailableParts.SelectedItems[0];
    
                if ((lvwAvailableParts.SelectedItems.Count == 0) ||
                    (lvwAvailableParts.SelectedItems.Count > 1))
                    return;
    
                txtPartNumber.Text = lviAutoPart.Text;
                txtPartName.Text = lviAutoPart.SubItems[1].Text;
                txtUnitPrice.Text = lviAutoPart.SubItems[2].Text;
    
                txtQuantity.Text = "1";
                txtSubTotal.Text = lviAutoPart.SubItems[2].Text;
    
                txtQuantity.Focus();
            }
    
            internal void CalculateOrder()
            {
                double partsTotal = 0.00D;
                double taxRate = 0.00D;
                double taxAmount, orderTotal;
    
                if (string.IsNullOrEmpty(txtTaxRate.Text))
                    txtTaxRate.Text = "7.25";
    
                foreach (ListViewItem lvi in lvwSelectedParts.Items)
                {
                    ListViewItem.ListViewSubItem SubItem = lvi.SubItems[4];
                    partsTotal += double.Parse(SubItem.Text);
                }
    
                try
                {
                    taxRate = double.Parse(txtTaxRate.Text) / 100;
                }
                catch (FormatException)
                {
                    MessageBox.Show("Invalid Tax Rate",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
    
                taxAmount = partsTotal * taxRate;
                orderTotal = partsTotal + taxAmount;
    
                txtSelectedPartsTotal.Text = partsTotal.ToString("F");
                txtTaxAmount.Text = taxAmount.ToString("F");
                txtOrderTotal.Text = orderTotal.ToString("F");
            }
    
            private void txtPartNumber_Leave(object sender, EventArgs e)
            {
                bool found = false;
    
                foreach (AutoPart part in Repository.AutoParts)
                {
                    if (part.PartNumber == long.Parse(txtPartNumber.Text))
                    {
                        txtPartName.Text = part.PartName;
                        txtUnitPrice.Text = part.UnitPrice.ToString("F");
    
                        if (string.IsNullOrEmpty(txtQuantity.Text))
                            txtQuantity.Text = "1";
    
                        txtSubTotal.Text = part.UnitPrice.ToString("F");
    
                        txtQuantity.Focus();
    
                        found = true;
                        break;
                    }
                }
    
                if (found == false)
                {
                    txtPartName.Text = "";
                    txtUnitPrice.Text = "0.00";
                    txtQuantity.Text = "0";
                    txtSubTotal.Text = "0.00";
    
                    MessageBox.Show("There is no part with that number.",
                                "College Park Auto-Parts",
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
    
            private void txtUnitPrice_Leave(object sender, EventArgs e)
            {
                double subTotal;
                double unitPrice = 0D;
                double quantity = 0.00d;
    
                try
                {
                    unitPrice = double.Parse(txtUnitPrice.Text);
                }
                catch (FormatException)
                {
                    MessageBox.Show("Invalid Unit Price!",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
    
                try
                {
                    quantity = int.Parse(txtQuantity.Text);
                }
                catch (FormatException)
                {
                    MessageBox.Show("Invalid Quandtity!",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
    
                subTotal = unitPrice * quantity;
                txtSubTotal.Text = subTotal.ToString("F");
            }
    
            private void btnAdd_Click(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(txtPartNumber.Text))
                {
                    MessageBox.Show("There is no part to be added to the order.",
                                    "College Park Auto-Parts",
                                    MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
    
                foreach (AutoPart part in Repository.AutoParts)
                {
                    if (part.PartNumber == long.Parse(txtPartNumber.Text))
                    {
                        ListViewItem lviSelectedPart = new ListViewItem(part.PartNumber.ToString());
    
                        lviSelectedPart.SubItems.Add(part.PartName);
                        lviSelectedPart.SubItems.Add(part.UnitPrice.ToString());
                        lviSelectedPart.SubItems.Add(txtQuantity.Text);
                        lviSelectedPart.SubItems.Add(txtSubTotal.Text);
                        lvwSelectedParts.Items.Add(lviSelectedPart);
                    }
                }
    
                CalculateOrder();
            }
    
            private void lvwSelectedParts_DoubleClick(object sender, EventArgs e)
            {
                ListViewItem lviSelectedPart = lvwSelectedParts.SelectedItems[0];
    
                if ((lvwSelectedParts.SelectedItems.Count == 0) ||
                    (lvwSelectedParts.SelectedItems.Count > 1))
                    return;
    
                txtPartNumber.Text = lviSelectedPart.Text;
                txtPartName.Text = lviSelectedPart.SubItems[1].Text;
                txtUnitPrice.Text = lviSelectedPart.SubItems[2].Text;
                txtQuantity.Text = lviSelectedPart.SubItems[3].Text;
                txtSubTotal.Text = lviSelectedPart.SubItems[4].Text;
    
                lvwSelectedParts.Items.Remove(lviSelectedPart);
                CalculateOrder();
            }
    
            private void miHelpContents_Click(object sender, EventArgs e)
            {
                Help.ShowHelp(this, hpCPAP.HelpNamespace);
                // Help.ShowHelp(this, hpCPAP!.HelpNamespace, HelpNavigator.TableOfContents);
            }
    
            private void miHelpIndex_Click(object sender, EventArgs e)
            {
                Help.ShowHelp(this, hpCPAP!.HelpNamespace, HelpNavigator.Index, string.Empty);
            }
    
            /* private void miHelpSearch_Click(object sender, EventArgs e)
            {
                Help.ShowHelp(this, hpCPAP!.HelpNamespace, HelpNavigator.Find, null);
            } */
    
            private void miHelpAboutCollegeParkAutoParts_Click(object sender, EventArgs e)
            {
                AboutCPAP ac = new AboutCPAP();
    
                ac.ShowDialog();
            }
    
            private void miFileExit_Click(object sender, EventArgs e)
            {
                Close();
            }
        }
    }
  52. To execute the application to test it, on the main menu of Microsofot Visual Studio, click Debug and click Start Without Debugging:

    College Park Auto-Parts

  53. On the main menu of College Park Auto-Parts, click Help and click one of the options (Contents or Index)
  54. Close the HTML Help window and return to College Park Auto-Parts
  55. On the main menu of the form, click File and click New Auto-Part...
  56. On the main menu of the New Auto Part, click Help and click Presentation...
  57. Close the HTML Help window and return to the New Auto-Part dialog box
  58. On the title bar of the New Auto Part, click the question mark button and click the Model combo box

    College Park Auto-Parts - New Auto Part

  59. In the Part # text box of the New Auto Part dialog box, type 928037 and press Tab

    College Park Auto-Parts - New Auto Part

  60. On the main menu of the New Auto-Part, click File and click New Make...
  61. In the Make dialog box, click the Help button
  62. Close the HTML Help window and return to the New Auto-Part dialog box
  63. Use the main menu of the New Auto Part dialog box to provide other information s follows:
    Year:      2017
    Make:      Buick
    Model:     Regal
    Category:  Alternators & Generators
    PartName:  DB Electrical Alternator
    UnitPrice: 218.74
  64. On the main menu of the form, click File and click Save Auto Part
  65. Create another part wiith the following information:
    Part #:    290741
    Year:      2015
    Make:      Ford
    Model:     F-150 XL 3.5L V6 Flex Regular Cab 2 Full - Size Doors
    Category:  Shocks, Struts & Suspension
    Part Name: Front Strut and Coil Spring Assembly - Set of 2
    UnitPrice: 245.68
  66. On the main menu of the form, click File and click Save Auto Part
  67. On the main menu of the form, click File and click Close
  68. On the main menu of College Park Auto-Parts, click File and click Exit
  69. Close Microsoft Visual Studio and return to your programming environment

Previous Copyright © 2004-2024, FunctionX Monday 08 May 2023 Next