Maximum Hight of a panel in Split Container - c#

How can I set the minimum & maximum height of a panel in a horizontal split container in my C# form?

I realize this question is old, but I couldn't find a suitable answer anywhere I looked. Some people suggested setting Panel1 as a fixed panel, which was not what I wanted. I solved this issue by using by using the splitcontainers sizeChanged and SplitterMoved events:
private const int Panel1MaxWidth = 1075;
private void splitContainer1_SizeChanged(object sender, EventArgs e)
{
if(splitContainer1.Panel1.Width > Panel1MaxWidth)
{
splitContainer1.SplitterDistance = Panel1MaxWidth;
}
}
private void splitContainer1_SplitterMoved(object sender, SplitterEventArgs e)
{
if (splitContainer1.Panel1.Width > Panel1MaxWidth)
{
splitContainer1.SplitterDistance = Panel1MaxWidth;
}
}
Just set the Pane1MaxWidth constant to whatever you want your maximum size of Panel1 to expand out to.

SplitContainer has 2 fields: Panel1MinSize and Panel2MinSize. To set the maximum size for panel1 just set the appropriate min size for panel2.

Irrespective of where the Panel is, you could normally specify the maximum height and width by doing:
panel1.MaximumSize = new Size(300, 300); //max 300 x 300
If you use SplitContainer and your Panel is inside the SplitContainer, and you want to change it while it is in the SplitContainer, however, you might need to identify if the Panel is in the Panel1 or Panel2 of the SplitContainer before you specify the max height and width as above. Something like this:
//assuming the name "panel1" in the Panel1 of the SplitContainer
Panel panel = splitContainer1.Panel1.Controls["panel1"];
panel.MaximumSize = new Size(300, 300); //max 300 x 300
However, if what you want is to change the splitContainer size itself, you could apply the MaximumSize for the splitContainer as well:
splitContainer1.MaximumSize = new Size(300, 300);
Or, if you want to change the splitContainer.Panel1 or splitContainer.Panel2, you could also try to play with SplitContainer.SplitterDistance property.

Related

How does OnPaint work with a ScrollableControl? [duplicate]

I draw my contents on a form inside OnPaint event with e.graphics.DrawLine(), etc... . So far I was drawing according to form size (resizing my elements) but now I'd like draw as big as I want, and if I draw outside the visible area (the place where object will be drawn is decided at runtime dynamically), I want user to use scroll bars in order to see parts of whole content which I draw.
I have enabled AutoScrolling but I don't know how it may help me when I don't have any controls on that form.
How can I do it?
Simply set the AutoScrollMinSize property to the size you want. The scrollbar(s) automatically appear when the form's ClientSize is smaller than this value. You'll also need to offset what you draw according to the scroll position, like this:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.AutoScroll = true;
this.AutoScrollMinSize = new Size(3000, 1000);
this.ResizeRedraw = true;
}
protected override void OnPaint(PaintEventArgs e) {
e.Graphics.TranslateTransform(this.AutoScrollPosition.X, this.AutoScrollPosition.Y);
e.Graphics.DrawLine(Pens.Black, 0, 0, 3000, 1000);
base.OnPaint(e);
}
}
First you should set AutoScroll = true; of that Form where you're drawing ,than the best way is to draw things into a Panel and Re-size the Panel to fit the Content drawled inside ,than the Form will Automatically Show it's Scroll Bar's.

How to change control's size and add new control while form is minimized

I have a windows form that has 2 panels inside it, one takes up left half of the form, one right. Now when a certain event occurs in my program (I receive a message from server for example), I want to add a new control (say a third panel) between the two existing, so I need to make make them smaller and move them to the sides of my form.
This can happen while the form is minimized and this is where my problem is. Panels Size returns [0,0] when the form is minimized so I cant use it for calculations.
So my first question is, how can I get "original" size of controls while the form is minimized?
And then, even if I somehow calculated the new Size (say I have 400px wide form with 2x 200px panels and I want the new 3rd panel to be 200px wide, so the old panels will become 100px wide), and applied it:
leftPanel.Size = new Size(100, 100);
then after the form is restored from minimized state to normal state, the panel will be way bigger than specified 100x100. Seems like it will restore to the forms ClientSize + the newly specified size
Therefore my question: how can I add and resize controls to form while the form is minimized?
Sample procedures to resize Panels hosted in a Form and adapt the Layout when a new Panel is inserted in the middle of the two existing.
The WindowState of the hosting Form Forms is not relevant (it can be minimized, maximized or in normal state).
► Using the first method, if the Form is maximized, the Panels will retain the initial Height.
► Using the second method, as it is now, the Panels' Height will be set to the Form's ClientSize.Height. It can of course be changed, setting the TableLayoutPanel Row(s) to an Absolute height instead of AutoSize.
Using the Docking feature alone:
Set the Form AutoSizeMode = Dpi
Add two Panels to the Form (e.g., panelLeft and panelRight)
Set the Width of both Panels to 200
Set panelLeft to Dock = DockStyle.Left and panelRight to Dock = DockStyle.Right
Right-click the Panel on the left and select SendToBack (!important)
Adjust the Form Size: it should be: (418, 138). Not important, just for a visual confirmation
In the Form constructor set this.ClientSize = new Size(400, 100);
Add a new public method to the Form:
public void AdjustPanelsWidth(int newWidth)
{
this.panelLeft.Width = newWidth;
this.panelRight.Width = newWidth;
}
When you need to add a new Panel in the middle of the two existing Panels:
(someForm represents the current instance of the minimized Form)
int newSize = 100;
someForm.AdjustPanelsWidth(newSize);
var p = new Panel() {
Size = new Size(newSize * 2, 100),
Dock = DockStyle.Fill
};
p.BringToFront();
someForm.Controls.Add(p);
Using a TableLayoutPanel:
Add a TableLayoutPanel to the Form
Set it to Dock = DockStyle.Top
Edit Columns and Rows to have 3 Columns and 1 Row
Set the Columns Styles in the TLP Designer as:
Columns:
(0) Percent 50%
(1) AutoSize
(2) Percent 50%
Row:
(0) AutoSize
Closing the TLP Designer, it should appear to have just two Columns: since the central one is auto-sized and it has no content, its Width is currently 0.
Add two Panels to the Form (not to the TableLayoutPanel directly)
Set the Size of the Panels = (200, 100)
Drag one Panel inside the left Column of the TLP and the other to the Column on the right
! Verify, in VS Property panel, that the Column property of Panel on the Left is Column 0
The same for the Panel on the Right: the Colum property must be Column 2
If the Column is wrong, edit it manually.
Select both Panels and set both to Dock = DockStyle.Fill
(now you should see the TLP completely filled by the Panels, both occupying 50% of the TLP Size)
Adjust the Form size as before (still not actually important)
In the Form constructor set this.ClientSize = new Size(400, 100); (as before)
Add a public method to the Form:
public void AddControl(Control control)
{
// Add a Control to Column 1 - Row 0
this.tableLayoutPanel1.Controls.Add(control, 1, 0);
panel.Dock = DockStyle.Fill;
}
To add a new Panel in the middle Column:
var p = new Panel() {
Size = new Size(200, 100),
BackColor = Color.Red,
Margin = new Padding(0)
};
someForm.AddControl(p);
Structure of a Form that implements the TableLAyoutPanel method described:
ClockMinimize() => Minimizes the Clock size, squeezing it between two other Panels
ClockShow() => Enlarges the Clock to overlap the other Panels, which will resize to completely fill the Form's ClientArea:
using System.Drawing;
using System.Windows.Forms;
public partial class frmClock : Form
{
public frmClock() => InitializeComponent();
private int m_ClientHeight = 0;
public void ClockShow()
{
this.panClock.Parent = this;
this.panClock.Size = new Size(360, 80);
this.panClock.Location = new Point(20, 10);
// Adjust the Clock Font Size here
this.panClock.BringToFront();
}
public void ClockMinimize()
{
this.panClock.Size = new Size(200, 40);
tableLayoutPanel1.Controls.Add(this.panClock, 1, 0);
this.panClock.Margin = new Padding(0, (m_ClientHeight - this.panClock.Height) / 2, 0, 0);
// Adjust the Clock Font Size here
AdjustPanelsWidth(panClock.Width / 2);
}
public void AdjustPanelsWidth(int newWidth)
{
this.panLeft.Width = newWidth;
this.panRight.Width = newWidth;
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this.MinimumSize = this.Size;
m_ClientHeight = this.ClientSize.Height;
}
protected override void OnClientSizeChanged(EventArgs e)
{
base.OnClientSizeChanged(e);
if (this.ClientSize.Height > 0) {
m_ClientHeight = this.ClientSize.Height;
}
}
}
I have come up with this workaround: I'm postponing resizing/moving until the form returns from minimized state, using async/await.
Instead of my original function:
public void changeControlPositionAndSize() {
//calculate new size and location based on size and location of neighboring controls
myPanel.Location = ...
myPanel.Size = ...
}
I'm now using:
public async Task changeControlPositionAndSize()
{
while (WindowState == FormWindowState.Minimized)
{
await Task.Delay(2000);
}
//calculate new size and location based on size and location of neighboring controls
myPanel.Location = ...
myPanel.Size = ...
}

What is the most efficient way to make random label location adjust to window size?

I have a label centered by the X coordinate on a form, and I'm trying to make it adjust its location on form resize.
So, I'm handling the Resize event to update label Location property.
private void SecondaryWindow_Resize(object sender, EventArgs e)
{
lblStartPointX = this.Width / 2 - lblSecondary1.Width / 2;
lblStartPointY = lblSecondary1.Location.Y;
lblSecondary1.Location = new Point(lblStartPointX, lblStartPointY);
}
It seems I can't directly assign some value to lblSecondary1.Location.X property (compiler considers it a mistake), so I came up with this code.
But it strikes me as not very efficient way to do the task... Just how much Point objects are created if you constantly resize the window, I wonder?
Since you want your Label to remain centered in the X coordinates when the Form resizes, move it's position to the center of the Form when it loads, setting the the Label's Anchor to AnchorStyles.Top:
private void form1_Load(object sender, EventArgs e)
{
label1.Anchor = AnchorStyles.Top;
label1.Location = new Point((this.Width - label1.Width) / 2, label1.Top);
}
It will keep its position when the Form.Width is resized.
If you want to keep it centered in both dimension, center it and remove any anchors. The control will remain in the middle of its parent Form:
private void form1_Load(object sender, EventArgs e)
{
label1.Anchor = AnchorStyles.None;
label1.Location = new Point((this.Width - label1.Width) / 2,
(this.Height - label1.Height) / 2);
}
There are multiply ways. I would recommend using WPF instead for responsive design.
When the Label is the only control, you can turn of Autosize, set the anchors to all sides, set the TextAlgin to Center and resize your Label, so it takes the whole space.
An other way would be to work with TableLayoutPanels. Takes some time to get used to it, but it comes near the Grid of WPF.
you can use : 2 options
1) go to label properties in that goto Layout >> Anchor then set the anchor as you want it.
2) go to label properties in that goto Layout >> Dock then set the Dock as required.

MS visual Studio Forms application : Can't get form to have less width then 100 Pixels

First question here so if I can improve something in anyway please let me know!
I am currently making a "multi-form" application.
It currently consists out of a launcher bar with various buttons and the launcher bar has a width of 150 pixels (This one is fine).
When the user presses a button another panel will open 10 pixels next to the the first panel with a width of 75. (I wanted to add the current buttons "subcategories" here)
But when calling the second form it keeps setting itself to 100 pixels (Well I think it is 100 pixels since it seems about 2/3 of the first panel)
private void button_click(object sender, EventArgs e)
{
if (activated == 0)
{
var new_y = new form2();
new_y.AutoSize = false;
new_y.Width = 75;
new_y.Height = this.Height;
new_y.Show();
activated = 1;
}
}
I stripped it of some additional code (positioning stuff) so if that could cause any problems please let me know.
But my question : How do I prevent the form setting itself to 100 pixels in width and make it the 75 pixels width I want it to be?
Thanks in advance!
Ps . FormBorderStyle is set to none
Try setting the MinimumSize property:
new_y.Width = 75;
new_y.Height = this.Height;
new_y.MinimumSize = new Size(75, this.Height);

set panel border thickness in c# winform

I have searching and the result cannot solve my case.
Actually I have a panel and I want the panel have thicker border than Windows given.
I need BorderStyle
BorderStyle.FixedSingle
thicker..
Thanks before
You have to customize your own Panel with a little custom painting:
//Paint event handler for your Panel
private void panel1_Paint(object sender, PaintEventArgs e){
if(panel1.BorderStyle == BorderStyle.FixedSingle){
int thickness = 3;//it's up to you
int halfThickness = thickness/2;
using(Pen p = new Pen(Color.Black,thickness)){
e.Graphics.DrawRectangle(p, new Rectangle(halfThickness,
halfThickness,
panel1.ClientSize.Width-thickness,
panel1.ClientSize.Height-thickness));
}
}
}
Here is the screen shot of panel with thickness of 30:
NOTE: The Size of Rectangle is calculated at the middle of the drawing line, suppose you draw line with thickness of 4, there will be an offset of 2 outside and 2 inside.
I didn't test the case given by Mr Hans, to fix it simply handle the event SizeChanged for your panel1 like this:
private void panel1_SizeChanged(object sender, EventArgs e){
panel1.Invalidate();
}
You can also setting ResizeRedraw = true using Reflection without having to handle the SizeChanged event as above like this:
typeof(Control).GetProperty("ResizeRedraw", BindingFlags.NonPublic | BindingFlags.Instance)
.SetValue(panel1, true, null);
You may see a little flicker when resizing, just add this code to enable doubleBuffered for your panel1:
typeof(Panel).GetProperty("DoubleBuffered",
BindingFlags.NonPublic | BindingFlags.Instance)
.SetValue(panel1,true,null);
To create a panel with border I place a panel in a panel. The "border panel" has the background color of the wanted border color and a padding, while the padding size is the wanted border thickness.
The advantage of this solution is that there is no flickering and no problems with resize.
This can be very simple be created in the designer or in code behind.
Code behind:
Panel panel_Border = new Panel();
Panel panel_Embedded = new Panel();
panel_Border.BackColor = Color.Green;
panel_Border.Controls.Add(panel_Embedded);
// this is the border thickness
panel_Border.Padding = new System.Windows.Forms.Padding(6);
panel_Border.Size = new System.Drawing.Size(200, 100);
panel_Embedded.BackColor = System.Drawing.SystemColors.Control;
panel_Embedded.Dock = System.Windows.Forms.DockStyle.Fill;
Create a new, slightly larger panel and set the background colour to Black (or whatever). Place the original panel INSIDE the larger panel.

Categories