Resizing tabs individually and programmatically in C# with Winforms - c#

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.

Related

Auto-resize multiple Forms rendered on Panel

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

Winform: Panel with scroll needs to have their width/height defined?

I've a winform usercontrol, that has a Panel, which is containing some TableLayout(which have also some other user controls).
All my components have a Dock=Fill and Autosize=True properties.
Currently, when I resize the windows, I don't have any scrollbar, the overflow is just no show.
I found that if I set the AutoScrollMinSize of my panel to something, I'm having those scrollbar appearing when I reach the set size.
My problem is that I add/remove elements on runtime, and I've also some things that I display or not depending the configuration. So for me it's very hard to hardcode here a value, either I've scrollbar too soon, or too late.
I'm sure there should be a way to configure my userControl, without having to calculate myself the size, to have the component displaying scrollbar, when the children's content cannot be displayed, do you know how?
Thank you!
You can change the AutoScrollMinSize value on the panel resize event or the form's resize event. That way, it won't be a fixed value and there will be a scrollbar available if the panel's child controls go beyond the panel edges -
private void panel1_Resize(object sender, EventArgs e)
{
panel1.AutoScrollMinSize = new System.Drawing.Size(panel1.Width, panel1.Height);
}

how to resize the size of a control automatically when the size of the form changes

I am drawing a rectangle on my form and on top of that I have a label that I dragged. Now I want to re-size the rectangle that contains label so that it changes automatically when the size of the form is changed(maximized and all).
I tried using
this.label1.Size = new Size();
but this causes my label or may be rectangle to disappeared from the form. I cannot see it in my form now.
Anchor and Dock properties do not serve my purpose. I have to hard code it.
Need help on how to solve this resizing problem.
Use the .Anchor property.
Check out the Anchor and Dock properties. They should be able to provide you with the functionality that you need.
You could also look in to using the .SetBounds() method in the resize event.
You can either use Dock property of the control which allows you to make it align with the left, right, top or bottom edge of the form or fill the entire form.
Or use Anchor property, which allows you to anchor the coordinates - e.g. when you set anchor to left, right, top, bottom, it will resize with the form.
If Dock and Anchor are no good then just set the Width and Height properties. By creating a default Size object and assigning that to your control you are basically assigning Width and Height to 0.
You should handle the SizeChanged event:
this.SizeChanged += new EventHandler(Form1_SizeChanged);
then in the envent handler method, you must arrange Size and Location of your control:
void Form1_SizeChanged(object sender, EventArgs e)
{
myControl.Size = new Size(w,h); // size of the control
myControl.Location = new Point(x,y); //coordinates from the upperleft corner of your control's container (the form in your case)
}
N.B.
AFAIK a label cannot be resized as you want (instead location is ok), because has a fixed size. Use textbox with Readonly and Multiline properties set to true
Try form Scale() method. But for me, it has a little strange behavior...

TabControl tab headings resize when changing font

I have an application that changes the font of every control to SegoeUI when it is run in Vista. It works fine, except for headings of tabpages (the buttons to click when switching from one tab to another).
Tab page headings do not grow vertically to accommodate a larger font size, they always remain the same height.
Is there a property that will allow the TabControl to handle this? (I have tried AutoSizeMode, but it only deals with a tab's width)
If not, what is the best way programmatically to resize the tabpage headings based on the font size?
There is an ItemSize property on the tab control that you can set to change the size of the tabs themselves. Also, to help you out with getting the size of the text, there's a MeasureString() method on the Graphics object that will give you back a SizeF struct with the size of the given text. That can help you determine if you need to change the ItemSize property. Some rough code:
Graphics g = this.tabControl1.TabPages[0].CreateGraphics();
SizeF s = g.MeasureString(this.tabControl1.TabPages[0].Text, this.tabControl1.TabPages[0].Font);

Best Layout of a WinForms UserControl with both Static and Dynamic Content?

I have a user control that has:
a) a buttons panel at the top (it always has to be visible)
b) a panel with controls that are dynamically added and re-sized at run-time. The controls can be many, so the panel has to be scrollable.
This user control will be hosted in a form, with the following requirements:
a) The initial size of the form will try to fit in maximum part of the dynamic content.
b) On changing the form size, the control has to be re-sized accordingly.
I had played with various anchoring, docking, and auto-sizing and I don't quite get it working in the way I want to. Sometimes, it is the scrolling that messes up, sometimes it is something else.
What combination of anchoring, docking, and auto-sizing of the panels, usercontrol, form should work best to achieve the desired outcome?
I succeeded to meet the requirements. Here is my solution:
The dynamic panel is anchored to the top and the bottom of the control. It does not AutoSize, it manually changes its MaximumSize and PreferredSize after change in the contents.
The form hosts the form using:
cntrl.AutoSize = true;
cntrl.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
cntrl.Dock = System.Windows.Forms.DockStyle.Fill;
The form subscribes to a custom control's event that notifies for the preferredHeight and it changes its own Height accordingly.
I'd go with a table layout panel. You can specify two rows by one column with the exact size for the buttons at the top and fill the rest with the bottom. Then put put either a normal panel or a flowlayoutpanel for the dynamic content in that area.
Without knowing the specifics of your problem I find multiple fill docked split containers with one fixed panel and/or a fixed slider usually creates a really handy resizing experience. You can also collapse panels very effectively too.

Categories

Resources