Single instance of a form
-
I have a project that had a Mainscreen that calls several forms via dll's. Visual inheritance if you will. There can only be one instance of each form running at a time. Therefore, I have the following class to pass each form through: using System; using System.Windows.Forms; using System.Collections.Specialized; using System.Runtime.InteropServices; namespace FormManager { public class FormLoader { private static HybridDictionary m_InitializedForms = new HybridDictionary(); public static void LoadFormType(Type formType) { Form frm = (Form)Activator.CreateInstance(formType); if (IsAlreadyLoaded(formType)) { frm.BringToFront();//this does not work. return; } FlagAsLoaded(formType); frm.Closed += new EventHandler(FormClosed); frm.Show(); } private static void FlagAsLoaded(Type formType) { m_InitializedForms[formType.Name] = true; } private static void FlagAsNotLoaded(Type formType) { m_InitializedForms[formType.Name] = false; } private static bool IsAlreadyLoaded(Type formType) { return ((m_InitializedForms[formType.Name] != null) && (bool)m_InitializedForms[formType.Name] == true); } private static void FormClosed(object sender, EventArgs e) { Form closingForm = (Form)sender; closingForm.Closed -= new EventHandler(FormClosed); FlagAsNotLoaded(sender.GetType()); } } } So, on the mainscreen I would simply call the Form2 from a button_click event like so: FormLoader.LoadFormType(typeof(Form2)); This works great. However, when I click on the button again, it does not bringtofront or have focus. I have done something very similar to this and it worked fine. I tried using the WIN32 API to bring it to front as well. That would instantiate another form. Still, no luck. Any suggestions would be great. Thanks in advance. -- modified at 10:29 Wednesday 14th December, 2005
-
I have a project that had a Mainscreen that calls several forms via dll's. Visual inheritance if you will. There can only be one instance of each form running at a time. Therefore, I have the following class to pass each form through: using System; using System.Windows.Forms; using System.Collections.Specialized; using System.Runtime.InteropServices; namespace FormManager { public class FormLoader { private static HybridDictionary m_InitializedForms = new HybridDictionary(); public static void LoadFormType(Type formType) { Form frm = (Form)Activator.CreateInstance(formType); if (IsAlreadyLoaded(formType)) { frm.BringToFront();//this does not work. return; } FlagAsLoaded(formType); frm.Closed += new EventHandler(FormClosed); frm.Show(); } private static void FlagAsLoaded(Type formType) { m_InitializedForms[formType.Name] = true; } private static void FlagAsNotLoaded(Type formType) { m_InitializedForms[formType.Name] = false; } private static bool IsAlreadyLoaded(Type formType) { return ((m_InitializedForms[formType.Name] != null) && (bool)m_InitializedForms[formType.Name] == true); } private static void FormClosed(object sender, EventArgs e) { Form closingForm = (Form)sender; closingForm.Closed -= new EventHandler(FormClosed); FlagAsNotLoaded(sender.GetType()); } } } So, on the mainscreen I would simply call the Form2 from a button_click event like so: FormLoader.LoadFormType(typeof(Form2)); This works great. However, when I click on the button again, it does not bringtofront or have focus. I have done something very similar to this and it worked fine. I tried using the WIN32 API to bring it to front as well. That would instantiate another form. Still, no luck. Any suggestions would be great. Thanks in advance. -- modified at 10:29 Wednesday 14th December, 2005
Instead of storign true or false as the dictionary values, you could try storing the form instances themselves. Then you could do something like
Form f = (Form)m_InitializedForms[Form2];
f.Show();You could simply compare the value to null to decide whether to instantiate or show an existing one. Regards Senthil _____________________________ My Blog | My Articles | WinMacro
-
I have a project that had a Mainscreen that calls several forms via dll's. Visual inheritance if you will. There can only be one instance of each form running at a time. Therefore, I have the following class to pass each form through: using System; using System.Windows.Forms; using System.Collections.Specialized; using System.Runtime.InteropServices; namespace FormManager { public class FormLoader { private static HybridDictionary m_InitializedForms = new HybridDictionary(); public static void LoadFormType(Type formType) { Form frm = (Form)Activator.CreateInstance(formType); if (IsAlreadyLoaded(formType)) { frm.BringToFront();//this does not work. return; } FlagAsLoaded(formType); frm.Closed += new EventHandler(FormClosed); frm.Show(); } private static void FlagAsLoaded(Type formType) { m_InitializedForms[formType.Name] = true; } private static void FlagAsNotLoaded(Type formType) { m_InitializedForms[formType.Name] = false; } private static bool IsAlreadyLoaded(Type formType) { return ((m_InitializedForms[formType.Name] != null) && (bool)m_InitializedForms[formType.Name] == true); } private static void FormClosed(object sender, EventArgs e) { Form closingForm = (Form)sender; closingForm.Closed -= new EventHandler(FormClosed); FlagAsNotLoaded(sender.GetType()); } } } So, on the mainscreen I would simply call the Form2 from a button_click event like so: FormLoader.LoadFormType(typeof(Form2)); This works great. However, when I click on the button again, it does not bringtofront or have focus. I have done something very similar to this and it worked fine. I tried using the WIN32 API to bring it to front as well. That would instantiate another form. Still, no luck. Any suggestions would be great. Thanks in advance. -- modified at 10:29 Wednesday 14th December, 2005
Here's your problem with the
FormLoader
. You check to see if the form type has been loaded and then try toBringToFront
a new instance of the form. Here's a rework of your class that does what you want.public class FormLoader
{
private static HybridDictionary m_InitializedForms = new HybridDictionary();public static void LoadFormType(Type formType, Form parentForm) { lock( typeof( FormLoader ) ) { if( eh == null ) { eh = new EventHandler( FormClosed ); } } if( IsAlreadyLoaded( formType ) ) { Form f = GetForm( formType ); f.Focus(); f.BringToFront(); return; } Form frm = (Form)Activator.CreateInstance(formType); FlagAsLoaded( formType, frm ); frm.Closed += eh; frm.Show(); } private static void FlagAsLoaded( Type formType, Form f ) { m\_InitializedForms\[formType.Name\] = f; } private static void FlagAsNotLoaded( Type formType ) { m\_InitializedForms.Remove( formType ); } private static bool IsAlreadyLoaded( Type formType ) { return ( ( m\_InitializedForms\[ formType.Name \] as Form ) != null ); } private static Form GetForm( Type formType ) { return ( m\_InitializedForms\[ formType.Name \] as Form ); } private static void FormClosed( object sender, EventArgs e ) { Form closingForm = sender as Form; if( closingForm != null ) { closingForm.Closed -= eh; FlagAsNotLoaded( sender.GetType() ); } } private static EventHandler eh;
}
Hope the helps. "we must lose precision to make significant statements about complex systems." -deKorvin on uncertainty
-
Here's your problem with the
FormLoader
. You check to see if the form type has been loaded and then try toBringToFront
a new instance of the form. Here's a rework of your class that does what you want.public class FormLoader
{
private static HybridDictionary m_InitializedForms = new HybridDictionary();public static void LoadFormType(Type formType, Form parentForm) { lock( typeof( FormLoader ) ) { if( eh == null ) { eh = new EventHandler( FormClosed ); } } if( IsAlreadyLoaded( formType ) ) { Form f = GetForm( formType ); f.Focus(); f.BringToFront(); return; } Form frm = (Form)Activator.CreateInstance(formType); FlagAsLoaded( formType, frm ); frm.Closed += eh; frm.Show(); } private static void FlagAsLoaded( Type formType, Form f ) { m\_InitializedForms\[formType.Name\] = f; } private static void FlagAsNotLoaded( Type formType ) { m\_InitializedForms.Remove( formType ); } private static bool IsAlreadyLoaded( Type formType ) { return ( ( m\_InitializedForms\[ formType.Name \] as Form ) != null ); } private static Form GetForm( Type formType ) { return ( m\_InitializedForms\[ formType.Name \] as Form ); } private static void FormClosed( object sender, EventArgs e ) { Form closingForm = sender as Form; if( closingForm != null ) { closingForm.Closed -= eh; FlagAsNotLoaded( sender.GetType() ); } } private static EventHandler eh;
}
Hope the helps. "we must lose precision to make significant statements about complex systems." -deKorvin on uncertainty
-
Here's your problem with the
FormLoader
. You check to see if the form type has been loaded and then try toBringToFront
a new instance of the form. Here's a rework of your class that does what you want.public class FormLoader
{
private static HybridDictionary m_InitializedForms = new HybridDictionary();public static void LoadFormType(Type formType, Form parentForm) { lock( typeof( FormLoader ) ) { if( eh == null ) { eh = new EventHandler( FormClosed ); } } if( IsAlreadyLoaded( formType ) ) { Form f = GetForm( formType ); f.Focus(); f.BringToFront(); return; } Form frm = (Form)Activator.CreateInstance(formType); FlagAsLoaded( formType, frm ); frm.Closed += eh; frm.Show(); } private static void FlagAsLoaded( Type formType, Form f ) { m\_InitializedForms\[formType.Name\] = f; } private static void FlagAsNotLoaded( Type formType ) { m\_InitializedForms.Remove( formType ); } private static bool IsAlreadyLoaded( Type formType ) { return ( ( m\_InitializedForms\[ formType.Name \] as Form ) != null ); } private static Form GetForm( Type formType ) { return ( m\_InitializedForms\[ formType.Name \] as Form ); } private static void FormClosed( object sender, EventArgs e ) { Form closingForm = sender as Form; if( closingForm != null ) { closingForm.Closed -= eh; FlagAsNotLoaded( sender.GetType() ); } } private static EventHandler eh;
}
Hope the helps. "we must lose precision to make significant statements about complex systems." -deKorvin on uncertainty
-
Curtis, Thanks for your help. One more thing. When I close the form, I am no longer able to bring it back up.
Hey, sorry about that. Change the body of the
FlagAsNotLoaded
method tom_InitializedForms.Remove( formType.Name );
Sorry, was removing on the
Type
and not theType.Name
. "we must lose precision to make significant statements about complex systems." -deKorvin on uncertainty -
Curtis, You are the man. Thanks for all of your help. I actually have to change it a bit to also control how MANY instances can be called for each form. However, I will have to take a stab at that later. When I do, do you mind if I hit you up? Thanks.
No problem. Thanks for the compliment. I had to do this exact same thing for an application that I build for mean people. But, the technology was new, I had never used C# before, and thought "Sure, they're a@@h0l3s, but it'll be fun." Well, it was fun while they left me alone! If you need more help, just post more messages in this thread. I'll try to keep an eye on it. That way, everyone can share the problems and solutions. "we must lose precision to make significant statements about complex systems." -deKorvin on uncertainty
-
Hey, sorry about that. Change the body of the
FlagAsNotLoaded
method tom_InitializedForms.Remove( formType.Name );
Sorry, was removing on the
Type
and not theType.Name
. "we must lose precision to make significant statements about complex systems." -deKorvin on uncertaintyNow that I think about your solution, you may want to change all the references to
formType.Name
to one of two things:formType.FullName
orformType
. Two instances of different classes can have the sameformType.Name
and exist in the same project. If I include the two form classes Project1.CurtisAwesomeForm and Project2.CurtisAwesomeForm, then they will both have the sameType.Name
s but differentType.FullName
s and theirType
s will not equate, either. Just my two cents. <smile /> "we must lose precision to make significant statements about complex systems." -deKorvin on uncertainty -
Now that I think about your solution, you may want to change all the references to
formType.Name
to one of two things:formType.FullName
orformType
. Two instances of different classes can have the sameformType.Name
and exist in the same project. If I include the two form classes Project1.CurtisAwesomeForm and Project2.CurtisAwesomeForm, then they will both have the sameType.Name
s but differentType.FullName
s and theirType
s will not equate, either. Just my two cents. <smile /> "we must lose precision to make significant statements about complex systems." -deKorvin on uncertainty -
You have a been a huge help. Thanks a lot. It is good to see that there are still people out there willing to help without makeing such a fuss if there is a loss of understanding.
No problem, amigo. "we must lose precision to make significant statements about complex systems." -deKorvin on uncertainty
-
No problem, amigo. "we must lose precision to make significant statements about complex systems." -deKorvin on uncertainty
Curtis, I am trying to control the number of instances of each form as well. So, working off of the previous code, I added this: public static void LoadFormType(Type formType, Form parentForm, int instances) { lock( typeof( FormLoader ) ) { if( eh == null ) { eh = new EventHandler( FormClosed ); } } if( IsAlreadyLoaded( formType ) ) { Form f = GetForm( formType ); f.Focus(); f.BringToFront(); return; } Form frm = (Form)Activator.CreateInstance(formType); FlagAsLoaded( formType, frm, instances );// DictionaryEntry[] myArr = new DictionaryEntry[m_InitializedForms.Count];//added m_InitializedForms.CopyTo( myArr, 0 );//added if(myArr[m_InitializedForms[formType.FullName]].Value <= instances)//added, clearly the cast types are wrong, but you get the idea { frm.Closed += eh; frm.Show(); } } private static void FlagAsLoaded( Type formType, Form f, int instances )// { m_InitializedForms[formType.FullName] = f; m_InitializedForms.Add(f, instances);//added } Then I would load a form as such: FormLoader.LoadFormType(typeof(Form2), this, 1); "1" indicating how many instances of the form should be allowed. Thanks again for your help. -- modified at 8:31 Monday 19th December, 2005