WinForms MDI inherid form has different propertie values in parent? - c#

I am doing some maintenance on a legacy winforms application.
The project uses form inheritance which makes my job much easier, but there is a strange problem. The setup is as follows:
FormBase : Form
FormBaseList : FormBase
FormClientList : FormBaseList
The problem I have now is with the property WindowsState.
I create a new FormClientList.
FormClientList f = new FormClientList();
f.MdiParent = this;
f.show();
Than I click on the maximize button so it becomes maximized.
Now I have a button (for debug purpose) on FormClientList to show me the value of the property WindowState and it returns maximized, as I expected.
In FormBaseList there is some code that needs to know the value of this property, but here it always returns normal, not maximized.
The code is on the doubleclick of a datagridview, which will create another form.
// code in FormBaseList
FormDetail detailForm = new FormDetail();
detailForm.MDIParent = this.MDIParent;
detailForm.Show();
if (this.WindowState == FormWindowState.Normal) // this = the maximized instance of FormClientList
{
// why do I get here when FormClientList is maximized ??
detailForm.Left = this.Left + 20;
detailForm.Top = this.Top + 20;
}
So it seems that the instance of this form has different values for this propertie depending from which class I run my testcode ?
How do I fix this ?

Related

Show A Form Side/Side Or Top/Bottom Of Parent Form C#

I need to put my progress/status window/form just below of the parent form or left/right side of the form.
It's very basic things and i know how to do that.. (the formal/basic way)..
Here is my code:
frmMain oTest;
oTest = new frmMain();
//oTest.FormBorderStyle = FormBorderStyle.None; (to make child form border/title bar less)
oTest.StartPosition = FormStartPosition.Manual;
oTest.Left = this.Left;
oTest.Top = this.Top + this.Height;
oTest.Width = this.Width;
oTest.ShowDialog();
But the problem is there is slight gap in between them.. please check the screenshot..
And if i try to set the child form border style to none, then the appearance became worse than above, though for my purpose i need to make the child form border style to none.
Here is the screenshot for that case:
Based my knowledge, it's look like windows theme/style change the visible appearance of the form look bit smaller where the original size is bit bigger than that?
so, my question is how i can make the child form same size as the parent form size regardless of the os theme?
thanks in advance
Based on my test, I reproduced your problem. I find that the form border width will affect the final result.
You could use the following code to get window border width.
int windowBorder = (this.Width - this.ClientRectangle.Width) / 2;
Completed code:
private void btnProcess_Click(object sender, EventArgs e)
{
Form1 oTest;
oTest = new Form1();
//oTest.FormBorderStyle = FormBorderStyle.None; (to make child form border/title bar less)
oTest.StartPosition = FormStartPosition.Manual;
int windowBorder = (this.Width - this.ClientRectangle.Width) / 2;
oTest.Left = this.Left;
oTest.Top = this.Top + this.Height-windowBorder;
oTest.Width = this.Width;
oTest.ShowDialog();
}
Result:

Remove top bar on child form

Making an MDI form, i wish to remove the top bar on all child forms. Working on Visual studio and c#. Any idea how? Im clueless.
Here the properies of the child form:
Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
Me.WindowState = FormWindowState.Normal
Me.MinimizeBox = False
Me.MaximizeBox = False
Me.ControlBox = False
Me.ShowIcon = False
Me.ShowInTaskbar = False
Me.Dock = DockStyle.Fill
Option 1: *
As mentioned in this answer, you can add a MenuStrip control to your MDI parent form, set its Visible property to false, and you should be good to go. The MDI child forms won't have a title bar displayed as long as they are maximized.
Option 2: *
Set the MdiParent Property of the child form.
Set the FormBorderStyle property of the child form to FormBorderStyle.None.
Set the Dock property of the child form to DockStyle.Fill. Note: This must come after setting the MdiParent or else it won't work.
That's it, you don't need to change any other properties (WindowState, ControlBox, etc.). Just maintain the order of the steps above.
Here's an example:
private void OpenAndDockMdiChild()
{
Form2 childForm = new Form2();
childForm.MdiParent = this; // This must come **before** setting
// the `Dock` property.
childForm.FormBorderStyle = FormBorderStyle.None;
childForm.Dock = DockStyle.Fill;
childForm.Show();
}
private void Form1_Load(object sender, EventArgs e)
{
OpenAndDockMdiChild();
}
Result:
Hope that helps.
* Tested with .NET 4.5.2 on both Windows 7 and Windows 10.

Place form1(No border style) inside of form2(Normal border style) [duplicate]

This question already has an answer here:
Add Form to a UserControl - is this possible?
(1 answer)
Closed 8 years ago.
I would like to know if it is possible to show/place a form1 INSIDE form2.
So that form1 is stuck inside form2.
Any help will be appreciated. thanks in advance.
Yes. The word you're looking for is MDI or Multiple Document Interface.
Just set form2's IsMdiContainer property to true
and set form1's MdiParent property to be form2 like so:
form2.IsMdiContainer = true;
form1.MdiParent = form2;
Of course, you cause the visual designer to write the first line for you by setting the property in the properties section:
EDIT
Here's an easy example.
Say you have 2 forms. FormContainer and FormChild.
FormContainer is the application's main form.
All you need to do is make sure that FormContainer's IsMdiContainer property is set to true and then you could add instances of other forms to this one by setting those instances' MdiParent property. Except for the main form, any instance of the Form class or a subclass is by default not visible.
public partial class FormContainer : Form {
public FormContainer() {
InitializeComponent();
this.IsMdiContainer = true;
// if you're not excited about the new form's backcolor
// just change it back to the original one like so
// note: The dark gray color which is shown on the container form
// is not it's actual color but rather a misterious' control's color.
// When you turn a plain ol' form into an MDIContainer
// you're actually adding an MDIClient on top of it
var theMdiClient = this.Controls
.OfType<Control>()
.Where(x => x is MdiClient)
.First();
theMdiClient.BackColor = SystemColors.Control;
}
private void FormContainer_Load(object sender, EventArgs e) {
var child = new FormChild();
child.MdiParent = this;
child.Show();
// if you wish to specify the position, size, Anchor or Dock styles
// of the newly created child form you can, like you would normally do
// for any control
child.Location = new Point(50, 50);
child.Size = new Size(100, 100);
child.Anchor = AnchorStyles.Top | AnchorStyles.Right;
}
}

Why is the SizingGrip of StatusStrip not showing?

I want to add a StatusStrip to a UserControl and resize this UserControl at runtime. Here is how I add the StatusStrip.
StatusStrip sb = new StatusStrip();
sb.BackColor = System.Drawing.SystemColors.ControlDark;
sb.Dock = DockStyle.Bottom;
sb.GripMargin = new Padding(2);
sb.SizingGrip = true;
sb.GripStyle = ToolStripGripStyle.Visible;
sb.LayoutStyle = ToolStripLayoutStyle.HorizontalStackWithOverflow;
this.Controls.Add(sb);
The StatusStrip is displayed at the bottom of the UserControl. However there is no SizingGrip (little Triangle) in the right bottom corner of the StatusStrip. Why not?
It's not showing up because a UserControl is not a sizable control at runtime. The StatusStrip, nay more specifically the sizing grip, was built to support the Form control.
Here is the code for ShowSizingGrip, a private property used during paint:
private bool ShowSizingGrip
{
get
{
if (this.SizingGrip && base.IsHandleCreated)
{
if (base.DesignMode)
{
return true;
}
HandleRef rootHWnd = WindowsFormsUtils.GetRootHWnd(this);
if (rootHWnd.Handle != IntPtr.Zero)
{
return !UnsafeNativeMethods.IsZoomed(rootHWnd);
}
}
return false;
}
}
at this point I can see two point of interest. First, HandleRef rootHWnd = WindowsFormsUtils.GetRootHWnd(this);, I can't test this class because it's internal, but there's a really good chance it's not going to return a window. However, even if it did, if said window was currently maximized, !UnsafeNativeMethods.IsZoomed(rootHWnd);, the sizing grip wouldn't show either.
My educated guess -- your window is maximized. I make that assumption because it appears Cody Gray was able to make it show up on a UserControl.

Show a child form in the centre of Parent form in C#

I create a new form and call from the parent form as follows:
loginForm = new SubLogin();
loginForm.Show();
I need to display the child form at the centre of the parent. So,in the child form load I do the foll:`
Point p = new Point(this.ParentForm.Width / 2 - this.Width / 2, this.ParentForm.Height / 2 - this.Height / 2);
this.Location = p;
But this is throwing error as parent form is null. I tried setting the Parent property as well, but didn't help. Any inputs on this?
Try:
loginForm.StartPosition = FormStartPosition.CenterParent;
loginForm.ShowDialog(this);
Of course the child form will now be a blocking form (dialog) of the parent window, if that isn't desired then just replace ShowDialog with Show..
loginForm.Show(this);
You will still need to specify the StartPosition though.
The setting of parent does not work for me unless I use form.ShowDialog();.
When using form.Show(); or form.Show(this); nothing worked until I used, this.CenterToParent();.
I just put that in the Load method of the form. All is good.
Start position to the center of parent was set and does work when using the blocking showdialog.
There seems to be a confusion between "Parent" and "Owner". If you open a form as MDI-form, i.e. imbedded inside another form, then this surrounding form is the Parent. The form property StartPosition with the value FormStartPosition.CenterParent refers to this one. The parameter you may pass to the Show method is the Owner, not the Parent! This is why frm.StartPosition = FormStartPosition.CenterParent does not work as you may expect.
The following code placed in a form will center it with respect to its owner with some offset, if its StartPosition is set to Manual. The small offset opens the forms in a tiled manner. This is an advantage if the owner and the owned form have the same size or if you open several owned forms.
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
if (Owner != null && StartPosition == FormStartPosition.Manual) {
int offset = Owner.OwnedForms.Length * 38; // approx. 10mm
Point p = new Point(Owner.Left + Owner.Width / 2 - Width / 2 + offset, Owner.Top + Owner.Height / 2 - Height / 2 + offset);
this.Location = p;
}
}
Assuming your code is running inside your parent form, then something like this is probably what you're looking for:
loginForm = new SubLogin();
loginForm.StartPosition = FormStartPosition.CenterParent
loginForm.Show(this);
For the record, there's also a Form.CenterToParent() function, if you need to center it after creation for whatever reason too.
When launching a form inside an MDIForm form you will need to use .CenterScreen instead of .CenterParent.
FrmLogin f = new FrmLogin();
f.MdiParent = this;
f.StartPosition = FormStartPosition.CenterScreen;
f.Show();
childform = new Child();
childform.Show(this);
In event childform load
this.CenterToParent();
You need this:
Replace Me with this.parent, but you need to set parent before you show that form.
Private Sub ÜberToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ÜberToolStripMenuItem.Click
'About.StartPosition = FormStartPosition.Manual ' !!!!!
About.Location = New Point(Me.Location.X + Me.Width / 2 - About.Width / 2, Me.Location.Y + Me.Height / 2 - About.Height / 2)
About.Show()
End Sub
When you want to use a non-blocking window (show() instead of showDialog()), this not work:
//not work with .Show(this) but only with .ShowDialog(this)
loginForm.StartPosition = FormStartPosition.CenterParent;
loginForm.Show(this);
In this case, you can use this code to center child form before display the form:
//this = the parent
frmDownloadPercent frm = new frmDownloadPercent();
frm.Show(this); //this = the parent form
//here the tips
frm.Top = this.Top + ((this.Height / 2) - (frm.Height / 2));
frm.Left = this.Left + ((this.Width / 2) - (frm.Width / 2));
It works in all cases, swap Form1 for your main form.
Popup popup = new Popup();
popup.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
popup.Location = new System.Drawing.Point((Form1.ActiveForm.Location.X + Form1.ActiveForm.Width / 2) - (popup.Width / 2),(Form1.ActiveForm.Location.Y + Form1.ActiveForm.Height / 2) - (popup.Height / 2));
popup.Show(Form1.ActiveForm);
On the SubLogin Form I would expose a SetLocation method so that you can set it from your parent form:
public class SubLogin : Form
{
public void SetLocation(Point p)
{
this.Location = p;
}
}
Then, from your main form:
loginForm = new SubLogin();
Point p = //do math to get point
loginForm.SetLocation(p);
loginForm.Show();
If you want to calculate your own location, then first set StartPosition to FormStartPosition.Manual:
Form Child = new Form();
Child.StartPosition = FormStartPosition.Manual;
Child.Location = new Point(Location.X + (Width - Child.Width) / 2, Location.Y + (Height - Child.Height) / 2);
Child.Show(this);
Where this is the main/parent form, just like Location.X.
Default value for StartPosition is FormStartPosition.CenterParent and therefore it changes the child's location after showing.
Make a Windows Form , then put option for it : CenterParent then use this Code :
yourChildFormName x = new yourChildFormName();
x.ShowDialog();
You can set the StartPosition in the constructor of the child form so that all new instances of the form get centered to it's parent:
public MyForm()
{
InitializeComponent();
this.StartPosition = FormStartPosition.CenterParent;
}
Of course, you could also set the StartPosition property in the Designer properties for your child form. When you want to display the child form as a modal dialog, just set the window owner in the parameter for the ShowDialog method:
private void buttonShowMyForm_Click(object sender, EventArgs e)
{
MyForm form = new MyForm();
form.ShowDialog(this);
}
If any windows form(child form) is been opened from a new thread of Main window(parent form) then its not possible to hold the sub window to the center of main window hence we need to fix the position of the sub window manually by means of X and Y co-ordinates.
In the properties of Subwindow change the "StartPosition" to be "Manual"
code in main window
private void SomeFunction()
{
Thread m_Thread = new Thread(LoadingUIForm);
m_Thread.Start();
OtherParallelFunction();
m_Thread.Abort();
}
private void LoadingUIForm()
{
m_LoadingWindow = new LoadingForm(this);
m_LoadingWindow.ShowDialog();
}
code in subwindow for defining its own position by means of parent current position as well as size
public LoadingForm(Control m_Parent)
{
InitializeComponent();
this.Location = new Point( m_Parent.Location.X+(m_Parent.Size.Width/2)-(this.Size.Width/2),
m_Parent.Location.Y+(m_Parent.Size.Height/2)-(this.Size.Height/2)
);
}
Here the co-ordinates of center of parent is calculated as well as the subwindow is kept exactly at the center of the parent by calculating its own center by (this.height/2) and (this.width/2) this function can be further taken for parent relocated events also.
As a sub form i think it's not gonna Start in the middle of the parent form until you Show it as a Dialog.
..........
Form2.ShowDialog();
i was about to make About Form.
and this is perfect that's i am searching for.
and untill you close the About_form you cant Touch/click anythings of parents Form once you Click for About_Form (in my case)
.Coz its Showing as Dialog
The parent probably isn't yet set when you are trying to access it.
Try this:
loginForm = new SubLogin();
loginForm.Show(this);
loginForm.CenterToParent()
If you have to center your childForm, from childForm then the code will be something like this. This code is in the childForm.cs
this.Show(parent as Form); // I received the parent object as Object type
this.CenterToParent();
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
CenterToParent();
}
Why not use this?
LoginForm.WindowStartupLocation = Windows.WindowStartupLocation.CenterOwner
(vb.net)

Categories