Cascade the MDI forms of a Splitter panel - c#

I am showing my MDI windows inside the main form but in one part of the splitter panel, like this:
Form2 f2= new Form2();
f2.MdiParent = this;
f2.Parent = this.splitContainer2.Panel2;
f2.Show();
but the problem is that I cannot cascade them if I write a code like this:
this.LayoutMdi(System.Windows.Forms.MdiLayout.Cascade);
"this" is the parent form. the main form.
Hoe can I cascade them?
thanks all.

You'll have to override the LayoutEngine for the SplitContainer panel. Microsoft has a good example here for creating a custom layout engine.
private void CascadeToolStripMenuItem_Click(object sender, EventArgs e) {
//LayoutMdi(MdiLayout.Cascade);
Rectangle bounding = this.splitContainer1.Panel1.DisplayRectangle;
Point nextFormLocation = bounding.Location;
foreach (Control c in this.splitContainer1.Panel1.Controls) {
if (!c.Visible) {
continue;
}
nextFormLocation.Offset(c.Margin.Left, c.Margin.Top);
c.Location = nextFormLocation;
c.BringToFront();
if (c.AutoSize) {
c.Size = c.GetPreferredSize(bounding.Size);
}
nextFormLocation.X = bounding.X + 20;
nextFormLocation.Y = bounding.Y + 20;
}
}
just add the above code to your cascade button and you'll get the basics of cascade.

Related

Access child form group control elements from mdi parent

Main form used as MDI parent form and it has got DevExpress.XtraBars.Bar and it contains a DevExpress.XtraBars.BarSubItem as a menu. When I click menu item, child form mounts this main form, an open file dialog is shown, selected an XML file and datas from XML file fill textbox controls. These textbox controls from child form are located in group control box.
I tried too many trials like this:
private void bbiHakimIsListesiBilgileri_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
if (ActiveMdiChild != null && ActiveMdiChild.Name == "_child_form")
{
var h = Control; // I don't know how I access GroupBox Control where located from child form.
GetXMLDatas(h);
}
else
{
var frm = new _child_form { MdiParent = this, Dock = DockStyle.Fill };
frm.Show();
var h = Control; // I don't know how I access GroupBox Control where located from child form.
GetXMLDatas(h);
}
}
Here is the GetXMLDatas method:
private void GetXMLDatas(Control k)
{
ofd.Title = #"Select an XML file.";
ofd.Filter = #"(*.xml)|*.xml|All files(*.*)|*.*";
ofd.FilterIndex = 1;
ofd.InitialDirectory = Tools.documents;
ofd.Multiselect = false;
ofd.ShowDialog();
if (string.IsNullOrEmpty(ofd.FileName)) return;
var data = XElement.Load(ofd.FileName).Descendants("field");
foreach (var f in Fields(k))
{
var value = data.FirstOrDefault(v => v.Attribute("key")?.Value == f.Name);
if (value != null) f.Text = value.Attribute("value")?.Value;
}
}
I don't know how I access GroupBox Control where located from child form in main form.
EDIT - 1: As a result, I want to find a groupbox control on an mdi child form from code on the mdi parent form. I have 3 mdi child form and two child forms have a groupbox. I want to reach these. Because if I manage to reach these two, I think, I can reach under these groupbox
EDIT - 2: After GuidoG's answer, I tried these:
MDI Child form name ise FormMDIChild_1. I added this code to FormMDIChild_1 text:
public GroupBox GetGroupBox()
{
return groupBox1;
}
Later, I added this code to mdi parent form called main form:
if (ActiveMdiChild is FormMDIChild_1)
{
GroupBox myGroupBox = (FormMDIChild_1)GetGroupBox();
}
But it gives errors like the screenhot:
Screenshot - 1
Screenshot - 2
Screenshot - 3
quick and dirty method :
create a method on each MDI Child form like this :
// suppose this mdi child is called FormMDIChild_1
public GroupBox GetGroupBox()
{
return Groupbox1;
}
in MDI Parent do this :
if (ActiveMdiChild is FormMDIChild_1)
{
GroupBox myGroupBox = ((FormMDIChild_1)ActiveMdiChild).GetGroupBox();
}
Better solution :
Create an MDI Child and call it for example FormBaseMDIChild
On this FormBaseMDIChild create a virtual method
public virtual GroupBox GetGroupBox()
inherit all other MDI Childs forms from FormBaseMDICHild and override the method GetGroupBox()
In MDI Parent do this
myGroupBox = ((FormBaseMDICHild)ActiveMdiChild).GetGroupBox();

How do I add form on tab control in c#

I have a form page with text boxes and data grid view and other forms that contain a tab control. I want to add the first form tab in the second form. I tried to write the code for the form to appear but it is larger than the tab container and doesn't fit. Only half of the form appears.
This is my code:
private void tcMainPage_SelectedIndexChanged(object sender, EventArgs e)
{
if (tcMainPage.SelectedIndex == 0)
{
GTOWN.PrintingPage BookInfo = new PrintingPage();
BookInfo.TopLevel = false;
BookInfo.FormBorderStyle = FormBorderStyle.None;
BookInfo.Dock = DockStyle.Fill;
tpSearch.Controls.Add(BookInfo);
BookInfo.Show();
}
}
this is the form
and that is what appears
Set your main FORM as a Container.
yourForm.IsMdiContainer = true;
Then add the child form to the tabPage:
private void tcMainPage_SelectedIndexChanged(object sender, EventArgs e)
{
if (tcMainPage.SelectedIndex == 0)
{
PrintingPage newFrm = new PrintingPage
{
MdiParent = this,
// This set the form parent as the tabClicked
Parent = tcMainPage.TabPages[0]
};
newFrm.Show();
}
}
my tab form work good in the same code
thank you all my code was correct but the problem was in tab property i deleted the tab and add another one and the code is working now
thank you
I face this issue and I create this if may help
public void addform(TabPage tp, Form f)
{
f.TopLevel = false;
//no border if needed
f.FormBorderStyle = FormBorderStyle.None;
f.AutoScaleMode = AutoScaleMode.Dpi;
if (!tp.Controls.Contains(f))
{
tp.Controls.Add(f);
f.Dock = DockStyle.Fill;
f.Show();
Refresh();
}
Refresh();
}
Forms are top-most objects and cannot be placed inside of other containers.
You may want to refactor your code so that the items on your Form are on a UserControl instead. At that point you can then add that UserControl to both a Form and a TabControl
public UserControl myControl(){ /* copy your current view code here */}
public Form myForm(){
Controls.Add(new myControl());
}
public Form myTabbedForm(){
var tabControl = new TabControl();
var page1 = new TabPage();
page1.Controls.Add(new myControl());
tabControl.TabPages.Add(page1);
this.Controls.Add(tabControl);
}

Resizing Panel Containing UserControl

I have a UserControl that contains invisible controls, to make them visible, the UserControl resizes.
I need to resize the Panel that contains the UserControl, but I don't know how.
This behavior is handled well by the Panel and Form classes without explicit sizing (and without the layout bugs introduced when the user has a high-DPI monitor or uses the large or extra-large font settings.
1) Create a Form with a docked FlowLayoutPanel.
2) Set the Form and FlowLayoutPanel's AutoSize to true and AutoSizeMode to GrowAndShrink
3) Add your panels and content.
4) Programmatically set the desired panel's Visible property to hidden
hiddenPanel.Visible = false;
5) or true
hiddenPanel.Visible = true;
Put this code in the usercontrol:
Size last = new Size(0, 0);
private void Me_Resize(object sender, System.EventArgs e)
{
if (last != new Size(0, 0)) {
this.Parent.Size = Size.Add(this.Parent.Size, Size.Subtract(this.Size, last));
}
last = this.Size;
}
Will also retain margins (e.g., if the panel is larger than your usercontrol or has other controls beside your usercontrol.)
If you'd like to resize it to a particular size, you can do it on the code behind:
Size panelSize = new Size(500, 500);
usercontrol1.Parent.Size = panelSize;
You could add this code to the usercontrol if that is where you wish to resize from.
To resize the control , call scale of to the control.
// To zoom in controls.
foreach (Control c in MyFlowLayoutPanel.Controls)
{
PictureBox ptc = c as PictureBox;
if (null != ptc)
{
Point pt = new Point(2, 2);
SizeF sf = new SizeF(pt);
c.Scale(sf);
}
}
// To zoom out controls.
foreach (Control c in MyFlowLayoutPanel.Controls)
{
PictureBox ptc = c as PictureBox;
if (null != ptc)
{
SizeF sf = new SizeF(0.5F, 0.5F);
c.Scale(sf);
}
}
I know that this topic is pretty old but I want to add my method, as well...
If you have a Panel containing a UserControl you can easially resize the panel.Controls by firing Form1_Resize event.
private void Form1_Resize(object sender, EventArgs e)
{
foreach (Control control in MasterPanel.Controls)
{
control.Size = MasterPanel.Size;
}
}
Just make sure that you anchor its content properly.

How do I put a panel of buttons into flow layout panel?

I have a panel of labels, buttons and image that I wish to put into a flow layout panel.
As seen in some tutorial, I understand that it is possible to auto align new and additional buttons into a flow layout panel.
what I would like to ask is that is it possible to put a panel WITHIN a flow layout panel and call multiple instances of the same panel to appear within the flow layout panel.
My panel code would be
this.panelNotification.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panelNotification.Controls.Add(this.button1);
this.panelNotification.Controls.Add(this.lblImage);
this.panelNotification.Controls.Add(this.lblName);
this.panelNotification.Controls.Add(this.lblLinkName);
this.panelNotification.Controls.Add(this.lblLinkLocation);
this.panelNotification.Controls.Add(this.lblLocation);
this.panelNotification.Location = new System.Drawing.Point(3, 3);
this.panelNotification.Name = "panelNotification";
this.panelNotification.Size = new System.Drawing.Size(506, 100);
this.panelNotification.TabIndex = 17;
So is it possible to include the whole panel into a flow layout panel? if yes, how do i do it. thank you.
Yes, you can put a Panel into a FlowLayoutoutPanel.
No, you can't put a control several times into a FlowLayoutoutPanel (in fact you can, but it is only displayed once).
But what you could do is writing some kind of Factory-Method that creates a new Panel with new Buttons/Labels/other Controls etc. every time you call it, and add these new instances to your FlowLayoutpanel. Something like this:
public class Form1
{
private Panel CreateNotificationPanel()
{
var p = new Panel { BackColor = Color.Red };
p.Controls.Add(new Button { Text = "Test" });
return p;
}
private void Form1_Load(System.Object sender, System.EventArgs e)
{
var flp = new FlowLayoutPanel { Dock = DockStyle.Fill };
flp.Controls.Add(CreateNotificationPanel());
flp.Controls.Add(CreateNotificationPanel());
flp.Controls.Add(CreateNotificationPanel());
this.Controls.Add(flp);
}
public Form1() { Load += Form1_Load; }
}
Another (and problably better) approach would be to create a UserControl that contains your Buttons/Labels/etc. instead of using a panel and adding all controls manually. Just create with the Designer and add new instances of the UserControl to the FlowLayoutPanel.

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