There are a lot of questions around about this for WinForms but I haven't seen one that mentions the following scenario.
I have three forms:
(X) Main
(Y) Basket for drag and drop that needs to be on top
(Z) Some other dialog form
X is the main form running the message loop.
X holds a reference to Y and calls it's Show() method on load.
X then calls Z.ShowDialog(Z).
Now Y is no longer accessible until Z is closed.
I can somewhat understand why (not really). Is there a way to keep Y floating since the end user needs to interact with it independently of any other application forms.
If you want to show a window using ShowDialog but you don't want it block other windows other than main form, you can open other windows in separate threads. For example:
private void ShowY_Click(object sender, EventArgs e)
{
//It doesn't block any form in main UI thread
//If you also need it to be always on top, set y.TopMost=true;
Task.Run(() =>
{
var y = new YForm();
y.TopMost = true;
y.ShowDialog();
});
}
private void ShowZ_Click(object sender, EventArgs e)
{
//It only blocks the forms of main UI thread
var z = new ZForm();
z.ShowDialog();
}
In x, you can put a y.TopMost = true; after Z.ShowDialog(). This will put y on the top. Then, if you want other forms to work, you can put a y.TopMost = false; right after the y.TopMost = true; This will put the window on top, but allow other forms to go over it later.
Or, if the issue is one form being put on top of the other, then you can change the start position of one of the forms in the form's properties.
You can change your main form (X) to be an MDI container form (IsMdiContainer = true). Then you can add the remaining forms as child forms to X. Then use the Show method instead of ShowDialog to load them. This way all child forms will float within the container.
You can add the child forms to X like this:
ChildForm Y = new ChildForm();
Y.MdiParent = this //X is the parent form
Y.Show();
Related
Our Application is displaying an "update-hint", if a new version is available.
This Update-hint should be "topmost" within the application, but, if the application is minimized, or send to the background, the update-hint should vanish as well..
Just using
this.TopMost = true;
will overlay "ANY" application that is currently running...
Is there a way to just "overlay" windows generated by the current application?
Desired:
application shows update-hint on top of every window, while application is in the foreground. Switching to another application will also send the update-hint to the background.
Desired: Update-Hint overlays ANY window of the current application:
Not desired: Update-Hint overlays FOREIGN applications as well:
Despite the name of the property, TopMost is actually your enemy here. To make a "floating form" stay above a main form, without obscuring other applications when they get focus, try it this way:
FormX f = new FormX();
f.Show(this);
"this" in this example, is the main form instance. It means the form you created is now owned by the main form, and will make it float above it. You get the added benefit of, when minimizing the main form, the floating forms will disappear, too.
I figured out a way to solve it.
Setting the owner of the UpdateHint is required, but in order to keep it on top of every application window, one has to change the owner, if a new Window is either shown, or activated.
Within our application, every Form is inheriting InterceptorForm, so all I had to do was to modify the InterceptorForm accordingly:
Change the Owner to this, except if there is no dialog, or this is the dialog itself:
public class InterceptorForm : Form
{
protected override void OnLoad(EventArgs e)
{
...
if (this.GetType() != typeof(UpdateHint) && MainWindow.updateHint != null)
{
Log.t("Setting owner on update hint during onload: " + this.GetType());
MainWindow.updateHint.Owner = this;
}
base.OnLoad(e);
}
and
protected override void OnActivated(EventArgs e)
{
if (this.GetType() != typeof(UpdateHint) && MainWindow.updateHint != null)
{
Log.t("Setting owner on update hint: " + this.GetType());
MainWindow.updateHint.Owner = this;
}
base.OnActivated(e);
}
}
The UpdateHint now stays on top of every window belonging to our application, but can be overlayed by any other application.
I am making a game using Windows Forms, and I feel that the easiest way to make different screens (Main Menu, Settings, Etc...) is using a separate form for each screen. I have looked up up many different ways to do this. Many people talk of using form2.Show(); this.Hide();, however, this creates a new popup window.
People have also suggested using this.IsMdiContainer = true; to create a new window inside of the current window, but this is also not the functionality I want.
EDIT: Another question, multiple-guis-one-window, explains slightly that this can be achieved using UserControls, but does not elaborate with any examples, or what I should do.
I want to completely replace the current form's functionality with that of a new form.
Is there a way to achieve this? If not, is there a good alternative?
As I understood, you want to keep the same form and change the data inside that form (to not get the effect that your form was closed and reopened again).
The problem is windows form does not support such thing directly (at least not in an optimal way), I would use another UI frameworks for that. However, if you want to stick though with windows forms, you may use GroupBox or Panel tools (available from windows form design tools in Visual studio). Here you can group your elements as required, and show/hide the group/panel as required.
That is one of the best available solution for windows form AFAIK.
You want to open child forms within main form then you should try this i have create it without any User Control.
I have manage one parent form and two child forms. child forms should be open within parent form.
frmMain(Parent Form)
Set frmMain Property as Following
WindowState = System.Windows.Forms.FormWindowState.Maximized
I have take 3 panel in frmMain window.
pnlMenu (For Display Menu)
Set pnlMenu.Dock = System.Windows.Forms.DockStyle.Top property
Set height of this panel as you require.
pnlMain (For Display Child Forms)
Set pnlMain.Dock = System.Windows.Forms.DockStyle.Fill property
pnlFooter (For Footer Section)
Set pnlFooter.Dock = System.Windows.Forms.DockStyle.Bottom; property
Set height of this panel as you require.
I have set menubar in pnlMenu(Click on that menu for display child form in pnlMain)
frmMain.cs
public void BindFormIntoMainForm(Form Main)
{
Main.TopLevel = false;
Main.WindowState = FormWindowState.Maximized;
Main.AutoScroll = true;
pnlMain.Controls.Clear();
pnlMain.Controls.Add(Main);
pnlMain.Refresh();
Main.Show();
}
private void childToolStripMenuItem_Click(object sender, EventArgs e)
{
frmChildForm1 ChildForm1 = new frmChildForm1();
BindFormIntoMainForm(ChildForm1);
}
private void childForm2ToolStripMenuItem1_Click(object sender, EventArgs e)
{
frmChildForm2 ChildForm2 = new frmChildForm2();
BindFormIntoMainForm(ChildForm2);
}
BindFormIntoMainForm method responsible for display child form in main window.
frmChildForm1 & frmChildForm2(ChildForm)
Set both form Property as Following
FormBorderStyle = System.Windows.Forms.FormBorderStyle.None
Now when you click on Child Form 1 Menu then display following output:
when you click on Child Form 2 Menu then display following output:
I think it can be helpful for you.
I am quite new to C#. Recently, I got stuck on a problem which is that I want to move two different forms together.
In more detail,
One big form (i.e. something as parent window) popups a small form.
What I want to do is to move these two forms at the same time by moving the parent window.
And, now I am creating the children (small) form by "Show()" method of Form.
The problem is that if I click the parent form, a small form goes behind the parent form (i.e. bigger form).
I know this is what should happen. However, I want to move these two forms by moving the bigger form while keeping the small form is front.
I also considered using "ShowDialog()". But, this prevent me from moving the bigger parent. I cannot event touch the parent window.
Set the child form's Owner property to the parent form:
this.childForm = new ChildFormClass();
child.Owner = this;
viewForm.ShowDialog();
//Can also be called like this instead of setting Owner property:
//viewForm.ShowDialog(this);
Reference: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.owner.aspx
This way, the child form will never be shown behind the parent.
EDIT:
To move both forms together, simply handle the parent's form Move event:
private void Form1_Move(object sender, EventArgs e)
{
Point p = this.PointToScreen(new Point(this.ClientRectangle.X, this.ClientRectangle.Y));
this.childForm.Location = p; //childForm needs to be a class member
}
Cheers
I have three forms in C#, now when I want to show form2 I hide the main one and show the form and then when done working, hide the second form and show the main form again - I am doing this with the simple hide and show functions in winforms. Now the problem is every called form is placed on a different location on the screen, while I want all of them to stay on the same place. How to do it?
Try setting the owner of the form when you call .Show()
You can also set the start position before you call show with .StartPosition = FormStartPosition.CenterParent
Or set the form.Location property after you call show
See here and here for more details
You no doubt have a bug in your code, you are creating a new instance of the form instead of calling Show() again on the hidden form object. That's a bad kind of bug, it will make your program consume a lot of machine resources, ultimately it will crash when Windows refuses to allow your process to create more windows.
To make your scheme work, you have to write code that distinguishes between a closed form and a hidden one. Best way to do that is to explicitly keep track of its lifetime with the FormClosed event. Like this:
private Form2 form2Instance;
private void button1_Click(object sender, EventArgs e) {
if (form2Instance == null) {
// Doesn't exist yet, so create and show it
form2Instance = new Form2();
form2Instance.FormClosed += delegate { form2Instance = null; };
form2Instance.Show();
}
else {
// Already exists, unhide, restore and activate it
form2Instance.WindowState = FormWindowState.Normal;
form2Instance.Visible = true;
form2Instance.BringToFront();
}
}
I asked this question previously and thought I had it figured out but it still doesn't work.
Form.Show() moves form position slightly
So I have a parent form that opens a bunch of children with show() and then when one is needed I use bringToFront() to display it. The problem is when show() is called the child form is aligned perfectly but when I use bringToFront it moves left and down 1 px which screws with my borders. I have set all the child forms startPosition properties to Manual before show()-ing them. I have set frm.location = new Point(x,y) when bringing to front. I've also tried explicity setting frm.location when show()-ing also. It still moves it left and down 1 px when I bringToFront(). Is there something with bringToFront() that doesn't let me change the location property of the form? Here is my code:
if (myNewForm != null)
{
myNewForm.MdiParent = this;
bool isFormOpen = false;
foreach (Form frm in Application.OpenForms)
{
if (frm.GetType() == myNewForm.GetType())
{
frm.WindowState = FormWindowState.Maximized;
frm.BringToFront();
frm.Location = new Point(-4, -30);
isFormOpen = true;
break;
}
}
if (!isFormOpen)
{
myNewForm.StartPosition = FormStartPosition.Manual;
myNewForm.Show();
}
}
EDIT: Ok so apparently Microsoft has a bug that lets StartPosition only work for ShowDialog() and not Show() but refuses to fix it: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=107589
But my application needs to keep all the different forms open and just bring them to the front when needed...so ShowDialog() could not be appropriately used in this instance correct? So what options do I have? Any?
If you wish to set the form location, you have to set the form's WindowState to Normal (on any other setting, the location is set for you according to the rules of that setting, so your value is ignored), and its StartPosition to Manual.
frm.WindowState = FormWindowState.Normal;
frm.StartPosition = FormStartPosition.Manual;
frm.BringToFront();
frm.Location = new Point(-4, -30);
I suppose the forms are moved by the code that handles the Show() (and BringToFront) requests, so you really cannot set the form's location - neither before nor after calling the method - because the form location will be updated after the code in your main window has executed (and left control back to the window message pump, in Win32 terms, basically).
I would use a subclass of Form for each of your forms and then add an explicit Point property that indicates the fixed position where that particular form is expected to be. Inside this class, override the OnShown virtual method (or perhaps the OnActivated method too) and simply update this.Location with the correct location.
That should force the forms to the correct position, even if some code inside windows forms changes it at some time.
Have you tried:
this.Location
or
Form.ActiveForm.Location ?
What about using a p/Invoke to MoveWindow? The link provided includes a C# example.
Have you tried showing the form, and then adjusting the Location?
Edit: Or, have you tried adjusting the Left and Top properties?