Background Form

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I have a form that I open with ShowDialog(). I have a background form that I
initially open to make a background behind the user input form. The code is
like this:

static Form BackForm=null;

public bool InputMethod()
{
if(BackForm==null){
BackForm = new Form();
// set up backform and make it maximized.
BackForm.Show();
}
Form InputForm=new Form();
// set up the input form here.
InputForm.ShowDialog(BackForm);
}

This basically works the way that I want it to, I call InputMethod() a bunch
of times, it puts up the BackForm once, then the smaller InputForm comes and
goes for input. The problem is that BackForm does not behave properly in
Windows, if you minimize InputForm, BackForm is still there, and does not
minimize, and can not be minimized. Is there a way to do this? Is there
something like an OnMinimize event that I could override for InputForm, and
minimize BackForm in it? Or a better way of having a background that does not
flicker between InputMethod() calls, without InputForm being maximized?
Thanks for any suggestions.
 
Hi Richard,

I performed a test based on your sample code and did see the problem you
described.

If an owner form (in this case, the BackForm) is shown in the normal
windows state, it will be minimized when the owned and modal form (in this
case, the InputForm) is minimized.

I have tried to subscribe the InputForm's SizeChanged event to minimize the
BackForm when the InputForm's minimized, but didn't succeed.

A workaround of this problem is to set the Location and Size property of
the BackForm to make it fill the entire working area of the screen
manually. Thus, when the InputForm is minimized, the BackForm is minimized.

The following is the sample code to do this:

private void button1_Click(object sender, EventArgs e)
{
if (BackForm == null)
{
BackForm = new Form();
BackForm.Show();
BackForm.Location = new Point(0, 0);
BackForm.Size = new
Size(Screen.PrimaryScreen.WorkingArea.Width,
Screen.PrimaryScreen.WorkingArea.Height);
}
Form InputForm = new Form();
InputForm.ShowDialog(BackForm);
}

Hope this helps.
If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
Thanks for the reply Linda. I added your code to my program, but it did not
work. So I made a small test program, and I still could not make it work. The
complete test program is listed below. When I minimize the main form, the
background form does not minimize too, it is still there, but it is greyed
and can not be minimized. I am compiling under .NET 2.0 if that matters.
Thanks for any suggestions that you have.



using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsApplication7
{
public class Form1 : System.Windows.Forms.Form
{
static Form BackForm=null;
static void Main()
{
if (BackForm == null){
BackForm = new Form();
BackForm.Show();
BackForm.Location = new Point(0, 0);
BackForm.Size = new
Size(Screen.PrimaryScreen.WorkingArea.Width,
Screen.PrimaryScreen.WorkingArea.Height);
}
Form InputForm = new Form();
InputForm.ShowDialog(BackForm);

}
}
}
 
Hi Richard,

Thank you for your reply!

I am sorry that I made a mistake in my first reply.

Whether an owned form is shown modally or modelessly, or whatever the
window state of the owner form is, the owner form won't be minimized
automatically when the owned form is minimized.

On the contrary, if the owned form is shown modelessly, the OWNED form will
be minimized automatically when the OWNER form is minimized.

To minimize the owner form when the modeless owned form is minimized, we
could handle the SizeChanged event of the owned form to make the owner form
minimized. However, this method doesn't apply to modal owned form, because
the modal owned form will be closed when the owner form is minimized. So I
suggest that you show the InputForm modelessly. The following is the sample
code.

static class Program
{
static Form BackForm = null;

static void Main()
{
if (BackForm == null)
{
BackForm = new Form();
BackForm.Show();
BackForm.Text = "back form";
BackForm.WindowState = FormWindowState.Maximized;
}
Form InputForm = new Form();
InputForm.SizeChanged += new
EventHandler(InputForm_SizeChanged);
InputForm.FormClosed += new
FormClosedEventHandler(InputForm_FormClosed);
InputForm.Text = "input form";
InputForm.Owner = BackForm;
Application.Run(InputForm);
}

static void InputForm_FormClosed(object sender, FormClosedEventArgs
e)
{
(sender as Form).SizeChanged -= new
EventHandler(InputForm_SizeChanged);
}

static void InputForm_SizeChanged(object sender, EventArgs e)
{
if ((sender as Form).WindowState == FormWindowState.Minimized)
{
(sender as Form).Owner.WindowState =
FormWindowState.Minimized;
}
}
}

Hope this helps.
If you have any question, please feel free to let me know.


Sincerely,
Linda Liu
Microsoft Online Community Support
 
Thanks. I tried your example program, and that is exactly the behavior that I
want. I then put it into my application, but I had some problems. It seemed
ok until I set the back form to be the owner of the input form. The second
time that I executed the application.run, it crashing saying that you can not
use a form that has been disposed. I understand that modeless forms do not
get disposed, and I thought I had removed my code that did that. I will have
to work on it some more and see what I can figure out. I appreciate your
assistance, and any additional suggestions. Thanks.
 
Hi Richard,

Thank you for your feedback!

I suppose that you should open the Input form from the main form. The
sample code I provided in my previous reply is used to illustrate how to
minimize the back form when the Input form is minimized.
The second time that I executed the application.run, it crashing saying
that you can not use a form that has been disposed.

Could you tell me what you mean by "The second time that I executed the
application.run"? Generally we only call the Application.Run method once in
the static Main method.

If the problem is still not solved, please show me the sample code and I
will follow up with you in time.

Sincerely,
Linda Liu
Microsoft Online Community Support
 
Thank you for the reply. I have made a new test program which shows the
problem. I want to call the input form a number of times, as the user chooses
different options. But I want the background form to stay in place
throughout, unless it is minimized. I think the test program below shows what
I am trying to do, and it crashes with the disposed message just as my real
application does. The other version, where the input form was modal, keeps
the background form, and does not crash, it just has the problem of not
minimizing. Thanks.



static class Program
{
static Form BackForm = null;

static void GetInput(string Prompt)
{
if (BackForm == null)
{
BackForm = new Form();
BackForm.Show();
BackForm.Text = "back form";
BackForm.WindowState = FormWindowState.Maximized;
}
Form InputForm = new Form();
InputForm.SizeChanged += new EventHandler(InputForm_SizeChanged);
InputForm.FormClosed += new
FormClosedEventHandler(InputForm_FormClosed);
InputForm.Text = Prompt;
InputForm.Owner = BackForm;
Application.Run(InputForm);
}

static void InputForm_FormClosed(object sender, FormClosedEventArgs e)
{
(sender as Form).SizeChanged -= new
EventHandler(InputForm_SizeChanged);
}

static void InputForm_SizeChanged(object sender, EventArgs e)
{
if ((sender as Form).WindowState == FormWindowState.Minimized)
{
(sender as Form).Owner.WindowState =
FormWindowState.Minimized;
}
}
static void Main()
{
GetInput("Enter Name: ");
GetInput("Enter Address: ");
GetInput("Enter City: ");
}
}
 
Hi Richard,

Thank you for your reply and the sample code!

I paste the sample code into a new WinForm application and run it.

When the first line of code 'GetInput("Enter Name: ");' in the static Main
method is executed, instances of BackForm and InputForm are created and
shown. When I close the InputForm, the BackForm is closed as well, which is
because the IntputForm is the main form.

When the second line of code 'GetInput("Enter Address: ");' in the static
Main method is executed, the variable 'BackForm' still refers to the
previous disposed instance of BackForm. Then the Owner property of the new
instance of the InputForm is assigned to the disposed instance of BackForm
so that an exception is thrown.

I suggest that you create another instance of Form as the main form and in
the main form's Load event handler, call the static GetInput method to show
the BackForm and InputForm. The following is a sample.

static class Program
{
static Form BackForm = null;

static void GetInput(string Prompt)
{
if (BackForm == null)
{
BackForm = new Form();
BackForm.Show();
BackForm.Text = "back form";
BackForm.WindowState = FormWindowState.Maximized;
}
Form InputForm = new Form();
InputForm.SizeChanged += new
EventHandler(InputForm_SizeChanged);
InputForm.FormClosed += new
FormClosedEventHandler(InputForm_FormClosed);
InputForm.Text = Prompt;
InputForm.Owner = BackForm;
InputForm.Show();
}

static void InputForm_FormClosed(object sender, FormClosedEventArgs
e)
{
(sender as Form).SizeChanged -= new
EventHandler(InputForm_SizeChanged);
}

static void InputForm_SizeChanged(object sender, EventArgs e)
{
if ((sender as Form).WindowState == FormWindowState.Minimized)
{
(sender as Form).Owner.WindowState =
FormWindowState.Minimized;
}
}
static void Main()
{
Form mainform = new Form();
mainform.Load += new EventHandler(mainform_Load);
Application.Run(mainform);
}

static void mainform_Load(object sender, EventArgs e)
{
GetInput("Enter Name: ");
GetInput("Enter Address: ");
GetInput("Enter City: ");
(sender as Form).WindowState = FormWindowState.Minimized;
}
}

Hope this helps.
If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support
 
Thank you Linda. The example works, but does not solve my problem. In my
system I making calls to the input form from another program, from an
unmanaged C program. So I can not have a single Application.Run() call for
everything. That is why I am trying to do this, so that the background form
stays on the screen between calls to the input form. When I first wrote it
and did not have the background form, everything would disappear from the
screen while the unmanaged C was running, and I want to avoid that. I am
going to experiment with some other ways to do the same thing. As always, if
you have suggestions, I appreciate it.
 
Just to follow up, I have now solved my problem. I did it by making the
background and the input screen be both modal, but I split it into a separate
thread. That way they can be minimized independently, and it all seems to
work fine. Thanks Linda for the help.
 
Back
Top