Re: Instance name of main form
- From: Peter Duniho <NpOeStPeAdM@xxxxxxxxxxxxxxxx>
- Date: Wed, 22 Aug 2007 10:55:59 -0700
Jon wrote:
My main form opens up another form, and from this other form, I'd like to access things in the main form. The problem is that although I know the name of the class of the main form (FormMain) I don't know the name of the instance of it since it was generated by the VS C# Express 2005 designer. In program.cs, I notice that there is the line:
Application.Run(new FormMain());
I guess I could replace this with:
FormMain fMain = new FormMain()
Application.Run(fMain);
although since it was generated by VS, I'm a bit hesitant of any knock-on effects.
What you propose is fine.
That, and the rest of this post, assumes you want a specific, easy-to-access, direct way to get at your form instance. In many cases, you may find that the Application.OpenForms property is sufficient. You would have to get the collection and then enumerate that list looking for the form you want. It's not quite as convenient to _use_ as the above techniques, but it certainly would be easier to implement initially, since all of that work has already been done for you (in other words, the "initial implementation" is zero effort on your part :) ).
I don't think making a singleton as suggested by the other reply is strictly necessary, but you might prefer it. Even creating a singleton class wrapper for your form though, you will need to modify the Program class as you've suggested, since the call to the Application.Run() method would need to use the singleton class to retrieve the form instance.
An alternative that wouldn't require changing the Program class (not that I think there's anything wrong with doing so) would be to create a singleton-like design in your FormMain class itself. It wouldn't be a true singleton, because you'd have to provide a public constructor that the Program class can use. But you could still provide a static accessor like a singleton has, and even throw an exception in the constructor if someone tries to instantiate more than one, to enforce the singleton nature:
class MainForm : Form
{
static MainForm _instance;
static public MainForm Instance
{
get { return _instance; }
}
public MainForm()
{
if (_instance != null)
{
throw new NotSupportedException("Only one instance of MainForm allowed");
}
_instance = this;
}
}
And if you don't really want the form to be a singleton, for whatever reason, you could instead change the above as follows:
class MainForm : Form
{
static List<MainForm> _instances = new List<MainForm>();
static public MainForm[] Instances
{
get { return _instances.ToArray(); }
}
public MainForm()
{
_instances.Add(this);
}
protected override void Dispose(bool fDisposing)
{
if (fDisposing)
{
_instances.Remove(this);
}
base.Dispose(fDisposing);
}
}
This lets you get a complete list of the instances. A couple of notes on the above:
1) I think the Dispose() method is correct, but don't take my word for it. :) I don't have to write Dispose() methods often enough for me to be sure that's an appropriate way to handle the end of the object's lifetime.
2) Using the above, it would be critical that you do properly dispose of unused forms. In particular, if you used the design with forms that are used as dialogs (they are shown with ShowDialog()), the form will never be disposed and release unless you do so explicitly, because the instance list retains a reference to it.
You should be writing correct code that disposes dialog forms anyway, so #2 shouldn't be an issue. It's just that the design short-cuts the finalizer fail-safe built into C#, because the form instance will always be reachable and thus not eligible for garbage collection and finalizing.
Of course, depending on how you use it, that could be a good thing. You could easily build on top of the above pattern a dialog form cache that retrieves already-instantiated instances of your dialog forms. One reason you might do that is if you want previous user entries in the dialog form to be retained, but don't want to have to write the code to do that explicitly.
Anyway, have I sufficiently confused the matter yet? :)
Pete
.
- Prev by Date: Re: Instance name of main form
- Next by Date: Re: C# Socket Programming
- Previous by thread: Re: Instance name of main form
- Index(es):