This article is designed to give you a simple understanding of how to
marshaling operations between child forms in an MDI application.
From the outset I would like to say that this is my preferred way, it may
not be the 'correct' way for some technical reason which I am not aware of
but I know that it works efficiently enough to use in my applications.
Whilst in most cases MDI's generally deal with the same document type but
here I am allowing for forms of different document types or forms.
In my FormsFrameWork I have created a class of forms; this class has an
Object array which will store a reference to the forms created by the MDI
parent.
See forms.cs.
Object[]
formObjects = new Object[0];
This
creates an Object array of zero length, we do not need a size when first
instantiated.
To make the formObjects available we declare a getter and setter for the
form objects.
// allow access to the forms
public Object[]
Forms
{
get{return(formObjects);}
set{formObjects
= value;}
}
So that we
can use the getter and setter we need to be able to add forms to the array
//add a new form to the object array
public int AddForm(Form f)
{
Array.Resize(ref formObjects,
formObjects.Length +1);
f.Tag =
formObjects.Length-1;
formObjects[formObjects.Length-1] = (Object)f;
return(formObjects.Length-1);
}
Notice I did
not specify the actual type of form to add, only that it is a Form and I am
storing a reference to that form, it can be any type of form you design.
In order to add the form to the array, we need to re dimension the array,
Array.Resize(ref formObjects,
formObjects.Length +1);
Before
going any further set the Tag property of the form to the index of the array
element
f.Tag = formObjects.Length-1;
Now we can add the form to the object array casting f as an Object so that
no exceptions are thrown
formObjects[formObjects.Length-1] = (Object)f;
The last thing to do is return the index into the array, this is needed
elsewhere.
Other things we need to do is to be able to do the following
Set the parent,
Set the Caption,
Show the Form,
Close a form by its index
Remove forms from the object array.
In every case we do not need to know what type of form it is only that it is
a form and to do that we need to cast the object back to a form, needless to
say that without casting to it's original form type we cannot get public
members or methods that are exclusive to the particular form type to call so
you can only call those methods that are of the base type.
We can call Close, Show and set Captions etc.
In order to remove a form from the object array we need to be able to re
designate the index into the array of the forms in the array so that you do
not get an exception trying to index a form that does not exist, this is
done using the following function which is called by the MDI parent AFTER
the FormClosed event is fired.
//-------------------------------------------------------------------------------------
// remove form from forms array
//-------------------------------------------------------------------------------------
public void RemoveForm(int frm_index)
{
//
temporary form objects (tfo), visible only in this function
Object[] tfo= new Object[0];
//rebuild
array leaving out form at frm_index
for(int i
= 0; i < formObjects.Length; i++)
{
if(i
!= frm_index ) //if
its not the form index
{
Form f
= (Form)formObjects[i];
Array.Resize(ref tfo,
tfo.Length +1); //add form to temp forms array
f.Tag = tfo.Length-1;
tfo[tfo.Length -1] = f;
}
}
formObjects
= tfo; //assign f to formObjects
}
Moving on to
the MDI parent, we instantiate the forms class
private forms fms
= new forms();
This is done before the constructor so that its scope is form wide; another
form wide variable is a current form index
private int childFormNumber
= 0;
This is
used by the MDI parent to marshal operations to the active form.
Creating new forms of the type needed is no big deal but we do need to keep
a handle on them so this is how it is done
private void
cSVFormToolStripMenuItem_Click(object sender, EventArgs e)
{
//create
the CSV form
createCSVForm();
}
//------------------------------------------------------------------------------------
// create a new document
form
//-------------------------------------------------------------------------------------
private void
createCSVForm()
{
//local variable, can use a global one
int frm_index = -1;
// form management, only needs to be
created once for the various forms that may be used in an application
// and should be placed before the form
constructor
// this is an Objects array so it does not
care what type of form you send it
//*********************************
// forms fms = new forms(); //uncomment if you want to use it here.
//*********************************
// creates an instance of form frmCSV (any form you
want to create)
frmCSV f = new frmCSV();
// add to the forms management array
returning the index into the array
// Note: you can get the index of the form
into the array from the forms Tag property
frm_index = fms.AddForm(f);
//make sure that parent is the MDI
otherwise will not show as MDI child.
fms.SetParent(this, frm_index);
//set the forms caption
fms.SetCaption(frm_index, "This is a
new form managed by the forms array | index = " +
frm_index.ToString());
//now we can show the form
fms.ShowForm(frm_index);
}
Join the conversation! Your thoughts help the community grow.