|
I'm having problems making my forms behave properly. It's very simple to demonstrate my problem with a test program as follows: (1) Create a default Windows Forms application. (Main form will be called Form1 by default.) (2) Add a new form to the application (will be called Form2 by default). (3) To Form1 class (in "Form1.cs") add an overload to OnLoad() as follows: protected override void OnLoad(EventArgs e) { base.OnLoad(e); new Form2().Show(this); } Now run the program. As you'd expect, two forms will be displayed with Form2 in front of Form1. These are the characteristics that I want (i.e. a normal window parent/child relationship): (A) If you close Form1, then Form2 also closes. This works. (B) If you close Form2, then Form1 does not close. This works. (C) If you click on either form, it brings it AND the other form to the front. This works. Test it by covering one of the forms by any other window (such as Notepad) and click on the other form. The hidden form will come to the front. (D) If you drag one of the forms in front of the other, it will appear in front of the one over which it is being dragged. THIS DOES NOT WORK! To see (D) failing, click on Form1 and drag it around over Form2. Notice how it is BEHIND Form2! At first I thought I could just omit the "this" argument to the Show() method like so: protected override void OnLoad(EventArgs e) { base.OnLoad(e); new Form2().Show(this); } If you try that, then (C) above doesn't work. How can I make all of (A)..(D) work? Anyone got any ideas?
|
| Matthew Watson Wednesday, October 07, 2009 12:52 PM |
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Form2 form = new Form2();
form.Show();
}
private void Form1_Activated(object sender, EventArgs e)
{
foreach (Form Form in Application.OpenForms)
{
Form.BringToFront();
this.BringToFront();
}
}
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Activated(object sender, EventArgs e)
{
foreach (Form Form in Application.OpenForms)
{
Form.BringToFront();
this.BringToFront();
}
}
}
This will give you desired functionality.
VB.NET to C#
http://www.developerfusion.com/tools/convert/vb-to-csharp/ - Proposed As Answer bySe3ker385 Thursday, October 08, 2009 10:21 AM
-
|
| Se3ker385 Wednesday, October 07, 2009 1:43 PM |
Thanks. :) I tried that, but unfortunately it causes the forms to flicker as they are brought to the front. I'll have to go with that if there's no non-flickery way though!
|
| Matthew Watson Wednesday, October 07, 2009 1:48 PM |
Why would you want this behaviour anyway? Tried using modal forms? VB.NET to C#
http://www.developerfusion.com/tools/convert/vb-to-csharp/ |
| Se3ker385 Wednesday, October 07, 2009 1:51 PM |
Why would you want this behaviour anyway? Tried using modal forms?
VB.NET to C# http://www.developerfusion.com/tools/convert/vb-to-csharp/
I basically want exactly the behaviour that you get when you open a form using the Show() overload that accepts a window for the parent. This behaviour is common enough that Microsoft added an overload specifically for it! However, it does the dragging weirdly, which is where the problem arises... A modal dialog box is definitely no good for our application; it has two separate windows that the user can place on different monitors, but both windows belong to the same application. |
| Matthew Watson Wednesday, October 07, 2009 2:00 PM |
I see, this makes sence for multi-monitor usage. But then again, if you put Form1 on first monitor and Form2 on second, they wouldnt overlap anyway. So no need for Form1 to be able to be draggable above Form2?? VB.NET to C#
http://www.developerfusion.com/tools/convert/vb-to-csharp/ |
| Se3ker385 Wednesday, October 07, 2009 2:05 PM |
Except there's nothing to stop the user from dragging it like that - and it's really disconcerting if the window that's being dragged is completely hidden while you drag it over the other window. I'm testing this on a three monitor system, where the main app window is maximized on the centre monitor, and I'm dragging the secondary window from the left monitor over the centre monitor to the right monitor. |
| Matthew Watson Wednesday, October 07, 2009 2:08 PM |
Your customers should get just one huge monitor and it would solve your problems :) VB.NET to C#
http://www.developerfusion.com/tools/convert/vb-to-csharp/ |
| Se3ker385 Wednesday, October 07, 2009 2:12 PM |
Actually, having one huge monitor is a real pain - you have to fiddle around sizing the two windows side-by-side. With two monitors, you can just maximize a window on each monitor. |
| Matthew Watson Wednesday, October 07, 2009 2:18 PM |
Or you can use a MDI approach. I almost never user more forms then the main form on the screen if i do, then those are dialogs then need to be answered and closed. VB.NET to C#
http://www.developerfusion.com/tools/convert/vb-to-csharp/ |
| Se3ker385 Wednesday, October 07, 2009 2:20 PM |
Heh, I've just found another problem with the original program. Try this: (1) Run the program. (2) Maximize Form1 on one monitor. (3) Maximize Form2 on the other monitor. (4) Minimize Form1. This correctly also minimizes Form2. (5) Click on Form1 in the task bar to restore it. This restores Form2 in its non-maximized state. :( |
| Matthew Watson Wednesday, October 07, 2009 2:21 PM |
I also considered MDI, but that actually rules out multimonitor support altogether. (And also it's confusing for the user, which is why Microsoft dropped it from Word.) |
| Matthew Watson Wednesday, October 07, 2009 2:26 PM |
Not really, its still considered a feature thats lacking in Word.. also Microsoft kind of fixed that with Windows7 the new taskbar makes all their SDI applications behave like MDI. Check out Adobe Photoshop for example they finally introduced MDI with the newest version, and its better then ever. Whats better this: http://img233.imageshack.us/img233/8633/snap009n.pngOr This: http://img71.imageshack.us/img71/2148/snap011.png
VB.NET to C#
http://www.developerfusion.com/tools/convert/vb-to-csharp/ |
| Se3ker385 Wednesday, October 07, 2009 2:37 PM |
Not really, its still considered a feature thats lacking in Word.. also Microsoft kind of fixed that with Windows7 the new taskbar makes all their SDI applications behave like MDI. Check out Adobe Photoshop for example they finally introduced MDI with the newest version, and its better then ever. Whats better this: http://img233.imageshack.us/img233/8633/snap009n.png Or This: http://img71.imageshack.us/img71/2148/snap011.png
VB.NET to C# http://www.developerfusion.com/tools/convert/vb-to-csharp/
Well assuming I wanted to edit some text, the second one is clearly superior! :) But in seriousness, you just showed me a picture of an application that has a tabbed document interface, not an MDI one... Although I guess a tabbed interface is a kind of MDI one, in fairness. |
| Matthew Watson Wednesday, October 07, 2009 3:06 PM |
The windowing model encouraged by Windows Forms isn't one you see used in many real applications. Well, any. A window always as an owner and will always be shown above the owner. If you don't specify an owner with the Show(owner) overload then Windows Forms will make the desktop the owner. At that point, the Windows window manager has no reason to change the Z-order of your Form2 instance when Form1 gets the focus. You can fix that by giving all of your windows an owner. That's the MDI model approach but that's one that comes with a lot of baggage. Just create your own owner window. Key point is that it doesn't have to be visible, use the TransparencyKey property. You will however have to manage proper shutdown, no great effort with Application.Exit(). Still, that doesn't make for a great windowing model. Check out the DockPanel Suite, it is popular, well designed and has the right price.
Hans Passant. |
| nobugz Wednesday, October 07, 2009 3:19 PM |
That looks quite interesting - I might consider that for use in other products in the future! As for the current one; it's way too far along to change the basic model now. I think we'll just have to put up with the main display being behind the child while the user is dragging it (which they will rarely be doing anyways). |
| Matthew Watson Wednesday, October 07, 2009 4:08 PM |
Hi Matthew, The behavior of parent child form as you have seen is by design. That means if you call a form as Show(parent), the form is a child form and always display in front of the parent one. Based on my understanding, you want all the forms belong to your application will be brought to the front when you click either form. That requirement seems like an MDI application behavior. When you have many forms open at a time and want to make them looks orderly, MDI can be a better choice. All the child forms of your application will be hosted in an MDI parent. That make easy to maintain all of them. Here is the reason of why MDI is a better choice: 1. When you close the parent form, all the child forms will be closed. 2. When you want to bring all the form to the front, you just need to bring parent form to the front. 3. Each child form can be brought to the front of other child forms. Hope this gives you some light. Anyway, thank to all of the participant to this thread. Sincerely, Kira Qian Send us any feedback you have about the help from MSFT at fbmsdn[At]microsoft.com
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! |
| Kira Qian Thursday, October 08, 2009 7:18 AM |
Thanks, but we ruled out MDI because we want the secondary display to be visible all the time, and to be shown on a separate monitor from the main application. |
| Matthew Watson Thursday, October 08, 2009 8:36 AM |
Just create your own owner window. Key point is that it doesn't have to be visible, use the TransparencyKey property. You will however have to manage proper shutdown, no great effort with Application.Exit().
Hans Passant. |
| nobugz Thursday, October 08, 2009 10:33 AM |
I think it's a bit easier to set this.Opacity = 0.0 rather than using the TransparancyKey. But that approach does look like it would work, and be fairly low impact! |
| Matthew Watson 22 hours 57 minutes ago |