formMain.vr.annotated

#
Using System
Using System.Collections
Using System.Collections.Generic
Using System.ComponentModel
Using System.Data
Using System.Drawing
Using System.Text
Using System.Windows.Forms
Using System.IO 

DclNamespace dotnet_project

BegClass formMain Extends(System.Windows.Forms.Form) Access(*Public) Partial(*Yes)

    /region Default Constructor
    
    BegConstructor Access(*Public)
#

Required for Windows Form Designer support

        InitializeComponent()
#

TODO: Add any constructor code after InitializeComponent call

    EndConstructor

    /endregion
#

It might be advantageous to declare forms globally. These lines do that. These lines are mostly here for discussion purposes.

    // DclFld ModalForm Type(formModal) New()
    // DclFld NonModalForm Type(formNonModal) New()

    DclConst NONMODAL Value(1)
    DclConst MODAL Value(2)
#

Fires when the form is first loaded.

    BegSr formMain_Load Access(*Private) Event(*this.Load)
        DclSrParm sender Type(*Object)
        DclSrParm e Type(System.EventArgs)
#

The notes.txt file provides the application notes displayed in this form.

        DclFld BinaryPath Type(*String)
#

If you wanted the current user's documents use this code.

        // BinaryPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
#

For this app the text file is stored in the same folder as the EXE file.

        BinaryPath = AppDomain.CurrentDomain.BaseDirectory
#

Read the entire file and store its contents in the textboxNotes textbox.

        textboxNotes.Text = File.ReadAllText(BinaryPath + '\notes.txt')
#

Populate the combobox.

        PopulateComboBox()
    EndSr
#

Populate the ComboBox with ComboBoxItems (a class provided in this project).

    BegSr PopulateComboBox
#

The combobox is populated with instances of the ComboBoxItem class. This is a user-provided class. Setting the DisplayMember tells teh combobox what property from the ComboBoxItem instance is displayed as text in the combobox.

        comboboxFormType.DisplayMember = 'Text'
#

Setting the ValueMember property isn't necessary. If you read about the SelectedValue property in the ComboBox docs is sure seems like if you set the ValueMember you should be able to use the ComboBox's SelectedValue property to determine the selected value (duh!). The docs are poorly written and SelectedValue only works when the Items property is databound to a list. That's more trouble than it's worth. Instead, as you'll see farther on down in the code, we'll avoid the the need for the SelectedValue property by using the SelectedItem property.

        // comboboxFormType.ValueMember = 'IntegerValue'
#

Add a combobox entry for the Show method.

        comboboxFormType.Items.Add(*New ComboboxItem('Show', NONMODAL))
#

Add a combobox entry for the ShowDialog method.

        comboboxFormType.Items.Add(*New ComboboxItem('ShowDialog', MODAL))
#

This code is the functional equivalent of the two Items.Add lines above. It illustrates how effective a good constructor can be in helping keep code succinct. With a good constructor you can add a item with one line of code; without, you need four lines per item plus one for a ComboBoxItem declaration. Less code isn't always better--don't ever sacrifice clarity for brevity. In this case, though, the brevity isn't penalizing.

        // DclFld ci Type(ComboBoxItem) 
        //
        // ci = *New ComboBoxItem()
        // ci.Text = 'Show'
        // ci.Value = 1
        // ComboBoxFormType.Items.Add(ci) 
        //
        // ci = *New ComboBoxItem()
        // ci.Text = 'ShowDialog'
        // ci.Value = 2
        // ComboBoxFormType.Items.Add(ci)
#

The combobox doesn't have the first item selected by default. Like all ordinal positioning in .NET, the SelectedIndex property is zero-based.

        comboboxFormType.SelectedIndex = 0
    EndSr
#

Show the form type selected.

    BegSr buttonDisplayForm_Click Access(*Private) Event(*this.buttonDisplayForm.Click)
        DclSrParm sender Type(*Object)
        DclSrParm e Type(System.EventArgs)
#

As mentioned above, the ComboBox's SelectedValue works only for databound lists. We didn't do that here--we used the Item property's Add method to build the list. And even though we didn't use a loop over a file as you might do for some dynamic ComboBox loading, if you did that you'd probably still use Item.Add. So, SelectedValue is rarely gonna be any help. Instead we'll use the SelectedItem property.

#

Declare a variable of type ComboBoxItem.

        DclFld SelectedItem Type(ComboBoxItem)
#

Assign the ComboBox's SelectedItem property to that work variable, sure to cast it as a ComboBoxItem (that's what *As ComboBoxItem does).

        SelectedItem = comboboxFormType.SelectedItem *As ComboBoxItem
#

Just to be defensive, make sure the SelectedItem isn't nothing. It can't be in this app because the initial SelectedIndex value was set to zero in the formMain_Load routine.

        If SelectedItem = *Nothing
#

Assign default value.

        Else
#

Display the form type displayed.

            If SelectedItem.IntegerValue = MODAL
                DisplayModalForm()
            Else 
                DisplayNonModalForm()
            EndIf  
        EndIf 
    EndSr
#

Display a non-modal form.

    BegSr DisplayNonModalForm
#

Declare and instance the NonModalForm. In AVR for .NET, you always need to instance a form before it is displayed. Depending on how frequently the form is displayed, and if you need its state to persist, it may be better to instance the form globally instead of at the method level (as is done here).

        DclFld NonModalForm Type(formNonModal) New()
#

Assign this form's textboxName.Text value to the textboxName.Text owned by the NonModalForm. To reference a control like this on another form, make sure the Modifier property for that control is Public.

        NonModalForm.textboxName.Text = textboxName.Text
#

There are three ways to show a non-modal form with AVR for .NET. A way is by calling the form's Show method without any arguments. In this case, if the parent(ie, *This form) is minimized the child form (ie, NonModalForm) is not minimized. This behavior may cause the end-user some confusion--especially if both forms show in the Windows taskbar.

        // NonModalForm.Show()
#

The Show method has an overload that accepts one argument: the form to act as the child form's parent. The Microsoft Show docs don't show this overload--but the Visual Studio object browser does and its been there a long time. Curiously, the Show method overload without an argument doesn't show in the object browser. And perhaps even more curiously, the object browser does show both an overload for ShowDialog without an arugment and overload for ShowDialog with the arugment. Go figure.

Calling the Show method with *This as its argument makes this form the child form's owner. One of the things this does is minimizes the child when the parent minimizes. This is probably the most wanted behavior and my preferred way of displaying a non-modal form.

        NonModalForm.Show(*This)
#

Like AVR Classic, AVR for .NET does have a Show opcode you could also use to show a non-modal form. AVR's Show opcode behaves like the Show method behavior shown discussed immediately above--ensuring the child form minimizes with the parent. There is no functional difference between

NonModalForm.Show(*This) // The form's Show method.

and

Show NonModalForm // AVR's Show opcode.

The Show opcode was included in AVR for .NET to help programmers coming to AVR
for .NET from AVR Classic. However, it may be confusing to VB.NET and C# programmers. You make the call--use either the Show method (with *This, probably) or the Show opcode.

        // Show NonModalForm
    EndSr
#

Display a modal form.

    BegSr DisplayModalForm
        DclFld ModalForm Type(formModal) New()
        DclFld dr Type(DialogResult) 

        DclFld ci Type(CustomerInfo)

        dr = ModalForm.ShowDialog()
        If (dr = DialogResult.OK) 
            ci = ModalForm.GetCustomerInfo()  
            MsgBox 'OK was clicked'
        Else
            MsgBox 'Cancel was clicked'
        Endif
#

Although it's disputed, it's a good practice to call a ShowDialog-displayed form's Dispose() before that form goes out of scope.

        ModalForm.Dispose()
    EndSr
        
EndClass