I have this Form with Panels. This Form has three Panels.
One Panel is collapsible and acts as a sidebar, the other one sits at the top and is there for showing title, the last one is the placeholder for the Forms being opened by clicking on one of the items being catered in Panel one.
Now what I want to do is resize (grow and shrink) the size (width only) of the placeholder Panel and the Form that is opened on the Panel according to the state of Panel one, which could either be expanded or collapsed. The dock is not working.
After some clarifications, it appears that the desidered layout and behaviour of the described Form is similar to this sample disposition:
A WinForms Form is embedded in another Form, and placed inside a Panel.
This Guest Form is stripped of its TopLevel coat-of-arms and parented to central Panel, as shown in this graphic example:
How do you dock these Panels to get this layout:
The Green Panel stays on top of the Form.
The DarkGray Panel lays on the left hand side of the Form.
The Gray Panel occupies the remaining space.
Insert three Panels on a Form container.
The Green Panel needs to maintain its position, it will never change:
Right click → SendToBack (!important :).
Dock → Top.
The DarkGray Panel is positioned under the Green Panel, on the left side of the Form. It needs to resize itself when needed, but will never cover the Green Panel:
Dock → Left
The Gray Panel needs to occupy the remaining space. It needs to resize itself when needed, but it will never cover Green Panel or Dark Gray Panel:
Right click → BringToFront (!important)
Dock → Center
The highest priority when docking, is assigned to the element which has the lowest z-order in the stack: the Green Panel, here.
The lowest priority is assigned to element with the highest z-order: the Gray Panel, which will then shrink and stretch among all other elements with higher priority (following the z-order).
How to embed the Form:
The easy part. It's a Form in our Project, no need to perform any magic to keep it alive when re-parented:
(This is just for 1 Form. With more Forms, you'll need something like a List<Control>:
//Define here the Form which will be embedded
[Your Form Class] EmbeddedForm;
private void button1_Click(object sender, EventArgs e)
{
EmbeddedForm = new [Your Form Class]() {
TopLevel = false,
Parent = panContainer,
Location = new Point(4, 4),
Enabled = true
};
EmbeddedForm.Show();
}
private void buttonShrink_Click(object sender, EventArgs e)
{
//Maybe insert a classic dotted mini-button to re-inflate the sidebar when needed
panelSideBar.Width = 6;
}
private void panelContainer_Resize(object sender, EventArgs e)
{
Rectangle rect = panelContainer.ClientRectangle;
rect.Inflate(-3, -3);
EmbeddedForm.Size = rect.Size;
}
If you allow your Container Panel to AutoScroll its content, the Resize event is not necessary.
Edit:
A PasteBin of the complete source code of the Form in sample graphics:
Embedded Forms
Related
I am trying to add another panel (with a splitter) to the right of the following image.
It currently has a Panel on the left with a splitter and 2 panels in the middle with a splitter.
How can i add a panel to the right of these, the panel must go all the way to the top and bottom of the form and be resizable with a splitter? thanks
Change Dock to None of the main split container (I guess its name is splitContainer1).
Add a new SplitContainer inside your form.
Drag and drop entire splitContainer1 inside the left panel of the new split container.
Change Dock of splitContainer1 back to Fill.
Change Dock of splitContainer3 (the new one) to Fill.
Starting from a blank form
In my form I have a panel with autosize = true.
The panel contains a SplitContainer control with 2 panels arranged horizontally.
The top panel contains a datagridview and the bottom panel contains a textbox.
Is there a way I can programmatically resize the top panel, and hence the entire SplitContainer based on changes in the height of the datagridview (determined by the number of rows)
UPDATE:
I am now able to resize the SplitContainer which has Dock = Bottom, however, the Layout event of the parent panel does not get fired in response to changes in the height of the SplitContainer control even thought the parent panel has Autosize = True
Try setting the splitter distance of the SplitContainer based on the height of the grid.
SplitterDistance Gets or sets the location of the splitter, in pixels, from the left or top edge of the SplitContainer.
Via https://msdn.microsoft.com/en-us/library/system.windows.forms.splitcontainer.splitterdistance(v=vs.110).aspx
Edit
What worked for me was to set Dock for the SplitContainer to None, which then allowed me to set the size of the SplitContainer (calling SplitContainer.Height) and having the panel resize itself to fit the SplitContainer.
Edit 2
To allow the SplitContainer to auto-size its width, you can try the following:
splitContainer.Width = this.ClientRectangle.Width - (splitContainer.Location.X * 2)
This.ClientRectangle.Width should get the width of the window without the border (if the parent is the form).
For some reason that I dont manage to understand, if I force the panel size in the code the object gets the right size.
If I define the panel size 300x300 in the IDE, later is shown smaller and the lines are not visible.
public Form1()
{
InitializeComponent();
panel1.Size = new Size(300, 300);
}
I have a splitContainer. I want to resize the form inside the splitContaner's panel to scale with when I move the splitter as below. But my form doesn't get redrawn. Any suggestion, thank so much!
private void splitContainer1_SplitterMoved(System.Object sender, System.Windows.Forms.SplitterEventArgs e)
{
// Define what happens when the splitter is no longer moving.
Cursor.Current = System.Windows.Forms.Cursors.Default;
statictisTableDisplayForm1.ClientSize = new Size(statictisTableDisplayForm1.Width, splitContainer1.SplitterDistance);
statictisTableDisplayForm1.Invalidate();
statictisTableDisplayForm1.Refresh();
Refresh();
}
Form supposed to be a top-level control which represents a window of your application. You should not embed forms as controls into other forms (well, unless there is no other option).
Usually, you should not resize and/or move controls manually. There are several layout options which allow automatic resizing of controls when the size of their container changes: Anchor, Dock.
So better create a UserControl which will contain controls and logic of your StatictisTableDisplayForm and place it to SplitContainer panel with Dock set to Fill. That will automatically resize user control when you move the splitter.
Note: if you have to use StatictisTableDisplayForm on it's own too, then just place same user control to this form.
I have a form with a tab control.
I want each tab to have its own interface with its own size, so that I can have button layouts as necessary.
I am, in this example, only altering height.
Currently I have the default form height and default tab height set (set by tab index 0).
I need a programmatic way to set each tab's height individually, and on event selectedIndexChanged, I am able to resize the form as needed relative to the currently selected tab, but I don't know how to change each tab's height individually.
How can I achieve this?
It sounds like you are talking more about the height of the form based on the selected tab than the height of each individual tab item.
Assuming the TabControl is Dock-Filled on a parent form, you can try this code to resize the form's height based on the content of the TabPage:
void tabControl1_SelectedIndexChanged(object sender, EventArgs e) {
var controls = tabControl1.SelectedTab.Controls.Cast<Control>();
if (controls.Any()) {
this.Height = controls.Max(x => x.Bottom) + 72;
}
}
The routine finds the lowest based control on the TabPage and then adds a fudge number of 72 to account for the height of the form's non-client area and other miscellaneous spacing issues.
But note, constantly changing the height of the form based on a tab selection can be a bit jarring to the end user, and is probably not considered a popular UX implementation.
I have a Windows Form window containing a FlowLayoutPanel, an OK Button, and a Cancel Button. The Form and FlowLayoutPanel both have AutoSize enabled, and the FlowLayoutPanel grows or shinks depending on the items placed in it.
I am trying to figure out how to position the OK and Cancel Buttons in the same row directly below the FlowLayoutPanel. I can't just specify positions for them since the FlowLayoutPanel above them grows and shrinks.
Any ideas on how to solve this?
Anchoring the buttons to the bottom of the form smells like a solution. If not, you can throw more panels at the problem but that's fugly. Simply using the Resize event can do wonders:
private void flowLayoutPanel1_Resize(object sender, EventArgs e) {
OKButton.Top = CancelButton.Top = flowLayoutPanel1.Bottom + 10;
}
Put your two buttons in another panel (anything will do).
Then put these two panels in another FlowLayoutPanel which arranges them top to bottom.