Working with Control Collections

by Andy 7. July 2008 14:49

As you know, I am busy migrating a project from eMbedded Visual Basic to .NET Compact Framework and C#. A key component in the legacy code is the way controls are populated and this is an area where I've had to workaround an issue in .NET Compact Framework.

In eVB you could do this:

Form(sControlName).Text = "Some value"

In other words, you could easily loop through all controls in a form and save names and values.

For iCounter = 0 To Form.Controls.Count - 1
sControlName = Form.Controls(iCounter).Name

You could then retrieve control names and values from the database and re-populate forms. In eVB, all controls in the form sit in the Form.Controls-collection. In .NET Compact Framework you can not address a control by its name in the Form.Controls-collection, only by its index in the collection:

Form.Controls[formControlIndex]

Furthermore, all controls in the form do not sit in the Form.Controls-collection. For instance, if you place controls in a panel, then those controls are found in the Form.Controls[IndexOfPanel],Controls-collection. I've solved these two migration issues by using a hashtable that stores the name of the control as the hash-key, and the control's index as the hash-value. In order to keep track of controls sitting in panels, I add the panel name to the control name when populating the hashtable.

First, when saving the data, I loop through the controls in the form:

foreach (Control formControl in Form.Controls)
{
   
/// Don't add data from disabled controls!
    if (formControl.Enabled)
    {
       
// Pull out control: the control, form and index
        // Is control a panel?
        if (formControl.GetType().ToString() == "System.Windows.Forms.Panel")
        {
           
// Get index of formControl, ie the panel
            formControlIndex = Form.Controls.IndexOf(formControl);

           
// Loop through controls in panel
            foreach(Control panelControl in
                Form.Controls[formControlIndex].Controls)
            {
                containerName = formControl.Name;

               
// Call save method. Pass ID, name of the form, the entire 
                // CONTROL that sits IN the panel, and the name of the panel.
                SaveControl(ID, sFormName, panelControl, containerName);
            }
        }
       
else
        {
           
// Call save method. Pass ID, name of the form, the entire 
            // CONTROL that sits IN the form, and the form name again.

            // The form name is the container.
            SaveControl(ID, sFormName, formControl, sFormName);
        }
    }
}

In the SaveControl-method, I can easily work with the control. For example, I can write:

sControlValue = ControlToSave.Text;

…to get the control's Text-property.

When opening the form I first need to create the hashtable of controls, so I can get at their index-values! The following method returns a hashtable with all controls in a form:

public Hashtable GetControls(Form form)
{
   
Hashtable formControlsHash = new Hashtable();
   
int formControlIndex;
   
int panelControlIndex;
   
string formControlName;
   
string panelControlName;

   
// Populate SmartControls with forms controls.
    foreach (Control formControl in form.Controls)
    {
       
// Get index of formControl
        formControlIndex = form.Controls.IndexOf(formControl);

       
// Get name of control.
        formControlName = formControl.Name;

       
// Add control to hashtable
        formControlsHash.Add(formControlName, formControlIndex);

       
if (formControl.GetType().ToString() == "System.Windows.Forms.Panel")
        {
           
// Loop through controls in panel
            foreach (Control panelControl in
              
form.Controls[formControlIndex].Controls)
            {
               
// Get index of current panelControl
                panelControlIndex =
                  form.Controls[formControlIndex].Controls.IndexOf(panelControl);

               
// Get name of panelControl. Name is constructed as
                // "formControlName.panelControlName"
                panelControlName = formControlName + "." + panelControl.Name;

               
// Add control to listbox
                formControlsHash.Add(panelControlName, panelControlIndex);
            }
        }
    }

   
return formControlsHash;
}

The ControlName is fetched from the database and since it contains any panel-name (if the control sits in a panel), then I can get their index-values from the hashtable. Note the lines of code that are made bold:

int delimeterPosition = sControlName.IndexOf(".", 0);

// If delimeter is found, then get container name also
if (delimeterPosition > 0)
{
   
// Container is not the form
    controlName = sControlName.Substring(delimeterPosition + 1);
    containerName = sControlName.Substring(0, delimeterPosition);

   
// Get the index of the container
    indexOfContainer = (int)formControlsHash[containerName];

   
// Get the index of the control
    indexOfControl = (int
)formControlsHash[sControlName];

   
// Get the control
    controlToSet = Form.Controls[indexOfContainer].Controls[indexOfControl];

   
// Set sControlName to be new name, after having peeled of container name.
    sControlName = controlName;
}
else
{
   
// Get the index of the control
    indexOfControl = (int
)formControlsHash[sControlName];

   
// Get the control
    controlToSet = Form.Controls[indexOfControl];
}

Now, I have a control that I can work with and set its value!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Andy | Compact Framework | Windows Mobile

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen