Reusing closed Winforms

H

Hector Santos

I'm new to C#.NET and Winforms.

I'm porting an MFC based applet to C#.NET and the main form has a tool
strip with bottons. The first button display another form:

public partial class MainForm : Form
{
MyOtherForm form1;
...

private void toolStripButton1_Click(object sender, EventArgs e)
{
// create or "recreate" closed form and show it.
// no duplicate forms.
....
}

}

Of course, I can do this:

form1 = new MyOtherForm();
form1.Show();

and will create a new instance of the form.

I need to have it to be one form only and when closed, recreate and/or
reshow it. I tried this:

if (form1 == null)
{
form1 = new MyOtherForm();
}
form1.Show();

and that works until the form is closed.

Sounds so simple. I looked at the all the members to see what is
needed there. I remember not, but if thats the only way, to have an
clumsy form1 to parent destroy event to reset form1 = null. Some
member in the class has to tell me it has been closed and/or need to
create a new instance.

Sounds so simple.

TIA
 
H

Hector Santos

I figured it out.

MyOtherForm form1 = null; // for understanding it starts null
..
private void toolStripButton1_Click(object sender, EventArgs e)
{
if (Form1 == null || Form1.Container == null)
{
Form1 = new MyOtherForm();
}
Form1.Show();
}

It did the job. But is that circumventing something more natural in C#?
 
H

Hector Santos

That wasn't it, it worked checking the ActiveControl member:

if (Form1 == null || Form1.ActiveControl == null)
{
Form1 = new MyOtherForm();
}
Form1.Show();
 
F

Family Tree Mike

I'm new to C#.NET and Winforms.

I'm porting an MFC based applet to C#.NET and the main form has a tool
strip with bottons. The first button display another form:

public partial class MainForm : Form
{
MyOtherForm form1;
...

private void toolStripButton1_Click(object sender, EventArgs e)
{
// create or "recreate" closed form and show it.
// no duplicate forms.
....
}

}

Of course, I can do this:

form1 = new MyOtherForm();
form1.Show();

and will create a new instance of the form.

I need to have it to be one form only and when closed, recreate and/or
reshow it. I tried this:

if (form1 == null)
{
form1 = new MyOtherForm();
}
form1.Show();

and that works until the form is closed.

Sounds so simple. I looked at the all the members to see what is needed
there. I remember not, but if thats the only way, to have an clumsy
form1 to parent destroy event to reset form1 = null. Some member in the
class has to tell me it has been closed and/or need to create a new
instance.

Sounds so simple.

TIA

I think you want to do the following when you create the form:

if (form1 == null)
{
form1 = new MyOtherForm();
form1.FormClosed += new FormClosedEventHandler(form1_FormClosed);
}
form1.Show();


Then, include this routine:

void form1_FormClosed(object sender, FormClosedEventArgs e)
{
form1.Dispose();
form1 = null;
}
 
J

Jason Newell

Hector,

I recognized your name from the MFC forums. Welcome to the .NET world ;-).

I'm not totally clear on what your ultimate goal is but here are some
tricks for you.

If you want to prevent the 2nd form from closing, you can override the
OnClosing() call in the 2nd form. Similar to handling WM_CLOSE in MFC.
My example is incomplete but you should get the idea.

protected override void OnClosing(CancelEventArgs e)
{
//base.OnClosing(e);
/* Prevent closing of window */
e.Cancel = true;
/* Hide window */
Visible = false;
}

Jason Newell
www.jasonnewell.net
 
H

Hector Santos

Jason said:
Hector,

I recognized your name from the MFC forums. Welcome to the .NET world ;-).


Thanks, I'll be hanging around more often here. :)
I'm not totally clear on what your ultimate goal is but here are some
tricks for you.


In this port, a picture of the desktop toolbar can be seen here in
this 14 years old MFC GUI client:

http://www.winserver.com/public/wcnavigator.wct

Each button languages a specific client window, new clients (i.e, games)

http://www.santronics.com/products/winserver/Casino.php

can be added using a 3rd party SDK.

The buttons don't create new instances, just start or restart existing
windows. See below.
If you want to prevent the 2nd form from closing, you can override the
OnClosing() call in the 2nd form. Similar to handling WM_CLOSE in MFC.
My example is incomplete but you should get the idea.

protected override void OnClosing(CancelEventArgs e)
{
//base.OnClosing(e);
/* Prevent closing of window */
e.Cancel = true;
/* Hide window */
Visible = false;
}


Ok, so one technique would be to hide it, rather than it being
disposed. ok, thanks. :)

Ultimately, I have to see if using the current design where each
button launcess an a specific EXE and use shared memory map file for
IPC communications between EXE and the toolbar main exe. If an EXE is
already active, minimized the button just reactives the exe display.
If it as closed, the button will relaunch it again, etc.

But since the first 4-6 are fixed (we write it), I am thinking just
make then part of the main toolbar exe. The only reason why it was
separate before was to allow for automated updates of an exe. When
the main toolbar starts an exe, before launching it, it checkes
version of the exe against any updates at the server. If an update it
is required, it is downloaded first. :) So probably. that means we
need to do WINFORM Dlls if we keep with this update idea per client Right?
 
H

Hector Santos

Hector said:
But since the first 4-6 are fixed (we write it), I am thinking just make
then part of the main toolbar exe. The only reason why it was separate
before was to allow for automated updates of an exe. When the main
toolbar starts an exe, before launching it, it checkes version of the
exe against any updates at the server. If an update it is required, it
is downloaded first. :) So probably. that means we need to do WINFORM
Dlls if we keep with this update idea per client Right?

So if I wanted to go the route where each window is a DLL, would sort
of C# project to add to my main toolbar solution project is this?

Windows Control Library?
 
J

Jason Newell

That or a standard Class Library will work. If you create a Class
Library, you'll need to "Add Reference" to System.Windows.Forms and
System.Drawing at the project level.

You'll probably also want to define a custom base form class so that you
can easily control consistency among these forms. Something like this:

namespace WindowsFormsControlLibrary1
{
public class HectorBaseForm : System.Windows.Forms.Form
{
protected override void
OnClosing(System.ComponentModel.CancelEventArgs e)
{
//base.OnClosing(e);
e.Cancel = true;
Hide();
}
}

public class CustomForm1 : HectorBaseForm
{
}

public class CustomForm2 : HectorBaseForm
{
}
}

Jason Newell
www.jasonnewell.net
 
H

Hector Santos

Hector said:
So if I wanted to go the route where each window is a DLL, would sort of
C# project to add to my main toolbar solution project is this?

Windows Control Library?

Yes and it worked, .NET ROCKS!!

I created a WcNavigator.Browser.DLL and added to my references.

First I saw that the IDE added "control" form, UserControl1, throw in
some toolbox controls, i.e. web browser, and tried to create an
instance of this in the main toolbar exe

if (dlgBrowser == null || dlgBrowser.ActiveControl == null )
{
dlgBrowser = new wcNavigator.Browser.UserControl1();
}
dlgBrowser.Show();

That didn't work, so I added a WinForm to the DLL project and that
worked nicely!

if (dlgBrowser == null || dlgBrowser.ActiveControl == null )
{
dlgBrowser = new wcNavigator.Browser.formBrowser1();
}
dlgBrowser.Show();

What would be the purpose of the usercontrol form? For the toolbox or
palette? Can I remove it without harm since the Winform seems to
provide the logic I need?

Sorry for all newbie .NET questions. :)
 
H

Hector Santos

Ok, Obviously I have a lot to learn as there seems to be many ways to
skin the same cat.

Ok, If is use a DLL approach, I can't have it reference to the main
EXE as that will bind it and hence the EXE could not update the DLL.
So it has to be dynamically loaded.

I see an example using the reflection library with Assembly.LoadFile().

This is what I have so far pulled from a google.net example:

Assembly u = Assembly.LoadFile("client1.dll");
Type t = u.GetType("client1.Form1");
if (t != null)
{
MethodInfo m = t.GetMethod("Show"); <--- NO GOOD
if (m != null)
{
return (string)m.Invoke(null, null);
}
}

Where did I go wrong? or is there a better way for dynamic .NET DLL
loading?

Thanks

---
 
H

Hector Santos

Ok, this is too freaking easy or am I ust setting myself up for problems?

public partial class wcnavMainForm : Form
{

Form dlgBrowser;
...

private void tbBrowser_Click(object sender, EventArgs e)
{
if (dlgBrowser==null || dlgBrowser.ActiveControl==null)
{
Assembly u =
Assembly.LoadFile(".....\\wcnav.browser.dll);
dlgBrowser =
(Form)u.CreateInstance("wcNav.Browser.Form1");
}
dlgBrowser.Show();

}
}

Is that good enough for loading a DLL with a form in it?

---
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top