Part 5: Adding the Utility’s Dialog Form

Tutorial Navigation | Previous: Part 4: Creating New Add-in Project | Next: Part 6: Converting VBA ArcObjects to CS

Continuing with the Visual Studio project from Part 4, we will now replicate the dialog form used by the VBA utility.

Note: In this tutorial we are performing a mostly line-by-line conversion of VBA to C#. At this stage, no attempt will be made to conform to all best practices for C# coding, such as robust and specific exception handling.

Resources

Files

See Part 4.

Video Demonstrations

The following videos are also linked from the relevant sections below. (opens in a new browser window or tab)

Add new form and add controls to it (duration 1:07)
Set properties of controls.. (duration 1:02)
Set properties of controls..continued (duration 0:58)
Finishing setting control properties and re-position (duration 1:14)
Set properties of form (duration 0:47)
Quick test of dialog form in ArcMap (duration 0:39)
Add form’s event handlers and private fields (duration 0:42)
Add properties and code to form class (duration 1:00)
Finish coding form class, add test code to button, and test in ArcMap (duration 1:10)

Adding and Designing the Dialog Form

Add a Blank Form to the Project

Video Demonstation: Add new form and add controls to it (duration 1:07)

Open the Solution Explorer if it is not visible (View | Solution Explorer). Right-click on the project name (“VBA_to_CS_Tutorial”) and select Add | Windows Form… from the context menu.

Locate and select the Visual C# Items item in the Categories list. Under Templates, select Windows Form. Change the Name to “frmStaggerOffset.cs”. Click the OK button.

A new blank form will be added to the project and will be displayed in design view.

Add Controls to the Form

Video Demonstation: Set properties of controls.. (duration 1:02)
Video Demonstation: Set properties of controls..continued (duration 0:58)
Video Demonstation: Finishing setting control properties and re-position (duration 1:14)

Use the image below (or the provided VBA_OffsetFeatures_Form.png image file) to resize the form and as a guide to adding visual controls from the toolbox.

Add a Label
Text: Be sure to have an active edit session.

Add a Label
Name: labLayerInfo
Text: Layer Info…

Add a Label
Text: Enter the amount of offset in map units (feet).

Add a Label
Text: North-South Route (East-West Offset)

Add a Label
Text: East-West Route (North-South Offset)

Add a TextBox (to the right of North-South Route label)
Name: txtOffsetX

Add a TextBox (to the right of East-West Route label)
Name: txtOffsetY

Add a Button
Name: btnOk
DialogResult: OK
Text: &OK

Add a Button
Name: btnCancel
DialogResult: Cancel
Text: &Cancel

Set Properties of the Form

Video Demonstation: Set properties of form (duration 0:47)

Click once on an empty area of the form to select it. Open the Properties window and edit the following properties for the form:

AcceptButton: btnOk
CancelButton: btnCancel
FormBorderStyle: FixedDialog
MaximizeBox: False
MinimizeBox: False
StartPosition: CenterParent
Text: Stagger Offset Features

Test the Dialog Form

Video Demonstation: Quick test of dialog form in ArcMap (duration 0:39)

In the Solution Explorer, open the StaggerOffsetButton.cs file (double-click it). It will display in the Code Editor.

Replace the code in the OnClick() method with the following code to display the new dialog form in ArcMap:

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
protected override void OnClick()
{
    try
    {
        // Create the form
        frmStaggerOffset staggerOffsetDialog = new frmStaggerOffset();
        // Display the form as a modal dialog
        staggerOffsetDialog.ShowDialog();
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message + "\n\n" + ex.StackTrace); 
        // Uncomment next line to re-throw the exception, which will halt ArcMap
        // throw;
    }
}

Note: Wrapping all your code in a “catch all” exception handler prevents unhandled exceptions from crashing ArcMap, and the message displayed will help you debug the problem. However, be aware that there is the potential for ArcMap to be left in an unstable state depending on the operation that caused the exception.

Start debugging (press green arrow button or F5).

Wait for ArcMap to load. Once it opens, open the provided VBAtoCS_Tutorial_01_v10.mxd map. Your toolbar and button should be where you placed on a tool panel.

Click the button to display the new dialog form.

Click the Cancel button to close the form, and close ArcMap to return to Visual Studio and stop debugging.

Provide Access to Dialog Values

Video Demonstation: Add form’s event handlers and private fields (duration 0:42)

Unlike VBA, in C# the form’s controls are private to the form class. In order to pass information between the form and the code in the button class we need to create some public properties, and hook into some events.

Right-click on a blank area of the form in design view and select View Code… from the context menu.

Initially, the form code file contains:

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
namespace VBA_to_CS_Tutorial
{
    public partial class frmStaggerOffset : Form
    {
        public frmStaggerOffset()
        {
            InitializeComponent();
        }
    }
}

Expand this to view the entire frmStaggerOffsets.cs file after making the following changes (+/-)

We need to pass a string with layer information to the dialog to display when it opens, and then return to numeric values for the offsets when closed.

Click on the frmStaggerOffset.cs [Design] tab page to display the form designer and click once on an empty area of the form to select it. Open the Properties window and switch to Events view by clicking the lightning bolt button:

Locate the FormClosing event and double-click on it to insert a new event handler in the form code file, which we will use to set the return values.

Repeat to add an event handler for the Load event.

View the form in the designer again and double-click on the OK button to insert an event handler for it as well.

At the top of the class add two new private double fields:

private double offsetX = 0;
private double offsetY = 0;

Video Demonstation: Add properties and code to form class (duration 1:00)

Next, add two public read-only properties to access the fields. (Notice the uppercase first letter, which differentiates the identifiers for the property and its field. C# is case-sensitive. You could also use differently spelled identifiers, but the manner shown is the widely used convention.):

public double OffsetX
{
    get { return offsetX; }
}
 
public double OffsetY
{
    get { return offsetY; }
}

When the OK button is clicked, we want to close the form. Locate the empty click event handler and enter code to call the form’s Close() method:

private void btnOk_Click(object sender, EventArgs e)
{
    this.Close();
}

Locate the empty Load event handler and add two statements to initialize the offset value controls to zero:

private void frmStaggerOffset_Load(object sender, EventArgs e)
{
    // Set defaults for offsets
    this.txtOffsetX.Text = "0";
    this.txtOffsetY.Text = "0";
}

We want to pass a string to the dialog, so we will add an overloaded constructor. Insert the following code directly under the existing constructor:

// Overload the constructor to accept an argument
public frmStaggerOffset(string layerInfo)
    : this()  // call the default constructor
{
    // Display the layer info on the form
    this.labLayerInfo.Text = layerInfo;
}

And finally, we need to validate the values entered for offsets in the FormClosing event handler:

private void frmStaggerOffset_FormClosing(object sender,
    FormClosingEventArgs e)
{
    if (this.DialogResult != DialogResult.OK)
    {
        // abort this method and skip validation
        return;
    }
 
    try
    {
        offsetX = Convert.ToDouble(this.txtOffsetX.Text);
        offsetY = Convert.ToDouble(this.txtOffsetY.Text);
    }
    catch (Exception ex)
    {
        MessageBox.Show("Please enter a valid number.\n\n" +
            ex.Message, "Invalid Offset Value(s)");
        e.Cancel = true; // Prevents form from closing
    }
}

Video Demonstation: Finish coding form class, add test code to button, and test in ArcMap (duration 1:10)

Test Setting and Getting Dialog Values

To test the new form, we will additional code to the Add-In Button’s OnClick() method.

Select the StaggerOffsetButton.cs file in the code editor, locate the OnClick() method and replace its contents with the following code:

protected override void OnClick()
{
    try
    {
      // Set the Layer Info
      string layerInfo = "Move xx features in:\n" + "SomeFeatureClassName";
 
      // Create the form
      frmStaggerOffset staggerOffsetDialog = new frmStaggerOffset(layerInfo);
 
      // Display the form as a modal dialog
      staggerOffsetDialog.ShowDialog();
 
      // Check if form was cancelled
      if (staggerOffsetDialog.DialogResult != DialogResult.OK)
      {
          // abort
          return;
      }
 
      // Get the offset values from the form
      double offsetX = staggerOffsetDialog.OffsetX;
      double offsetY = staggerOffsetDialog.OffsetY;
 
      // Display the offset values for testing
      MessageBox.Show("offsetX: " + offsetX.ToString() +
          "\noffsetY: " + offsetY.ToString());
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message + "\n\n" + ex.StackTrace);
    }
}

Start debugging (press green arrow button or F5).

Wait for ArcMap to load. Once it opens, open the provided VBAtoCS_Tutorial_01_v10.mxd map. Your toolbar and button should be where you placed on a tool panel.

Click the Add-In’s button to display the new dialog form.

Notice the layer info label text has been fill with:
Move xx features in:
SomeFeatureClassName

Enter various valid (numeric) values for the offsets and click the OK button to verify they are returned correctly from the dialog.

Try some invalid (non-numeric) values to verify error handling.

Close ArcMap to return to Visual Studio and stop debugging.

Now that the dialog form is functional, it is time to turn our attention to converting VBA ArcObjects code to C#.

Tutorial Navigation | Previous: Part 4: Creating New Add-in Project | Next: Part 6: Converting VBA ArcObjects to CS

  1. #1 by Ann on April 27, 2016 - 10:21 am

    Good tutorial. I have a quick question:
    This code is in a VBA module called CreateData:
    Public doing As String

    Public Function CreateSQLGDB(cmdstrin As String) As IWorkspace

    Dim pWorkspace As IWorkspace

    Dim pPropset As IPropertySet
    Set pPropset = New PropertySet
    pPropset.SetProperty “CONNECTSTRING”, connStr
    Dim pWorkspaceFact As IWorkspaceFactory

    Set pWorkspaceFact = New OLEDBWorkspaceFactory
    Set pWorkspace = pWorkspaceFact.Open(pPropset, 0)

    Dim cmdstr As String
    cmdstr = cmdstrin
    pWorkspace.ExecuteSQL cmdstr
    Set pWorkspace = Nothing
    Set pPropset = Nothing

    End Function

    How can I convert it into C#? Thanks

(will not be published)