C# How to set control height in relative height - c#

My form contains a tab control. On one tab, I have three groupboxes. Each groupbox must have the height of one third of the height of the tab.
Right now I have this code on the layout event of the tab control:
// Determine the position of the group panels (gp)
this.SuspendLayout();
int oneThird = (tabPanel.Height - 5) / 3;
if (_currentQuestion != null && _currentQuestion.QuestionTypes == QuestionTypes.Infofield)
{
gpExplanation.Visible = false;
gpFillInHelp.Visible = false;
gpFillInQuestion.Height = oneThird * 3;
}
else
{
gpExplanation.Visible = true;
gpFillInHelp.Visible = true;
gpFillInQuestion.Height = oneThird;
gpExplanation.Height = oneThird;
gpFillInHelp.Height = oneThird;
}
// Determine position of the appointment and achievement group panels
int height = tabPanel.Height - 30;
int half = height / 2;
pnlAppointment.Height = half;
this.ResumeLayout();
I also have this code in the constructor of my form:
// Set styles which prevent screen flickering
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
this.DoubleBuffered = true;
What is in your eyes the best way to set the height of the groupboxes? When the form resizes, the groupboxes height must be one third of the panels height.
I also want as less as possible flickering on the screen.

You can use a TableLayoutPanel for this. In the panel you can specify the RowStyle
such that it sized as a percentage of the parent control:
tableLayoutPanelGroupBoxes.ColumnCount = 1;
tableLayoutPanelGroupBoxes.RowCount = 3;
tableLayoutPanelGroupBoxes.RowStyles.Add(new RowStyle(SizeType.Percent, 33.33333F));
tableLayoutPanelGroupBoxes.RowStyles.Add(new RowStyle(SizeType.Percent, 33.33334F));
tableLayoutPanelGroupBoxes.RowStyles.Add(new RowStyle(SizeType.Percent, 33.33334F));
Just set the DockStyle on your group boxes to DockStyle.Fill and add them to the table layout panel. You can use the designer to do this.

Use Achor property of the group boxes.

Related

Auto resize to fill all multi panels

How to size all panels as fill in form1 window without changing panels size? I searched on Google. very difficult to find. That why i want to help. like in below Thanks.
If 3 panels this will be resized:
4 Panels:
5 Panels:
9 Panels:
You can use a FlowLayoutPanel. Insert in your form and set Dock=Fill in the designer. Add this const to your form:
private const int PanelSize = 200;
In the constructor:
this.flowLayoutPanel1.Resize += this.OnFlowLayoutPanel1_Resize;
this.OnFlowLayoutPanel1_Resize(this.flowLayoutPanel1, EventArgs.Empty);
And use this method to create/destroy the panels:
private void OnFlowLayoutPanel1_Resize(object sender, EventArgs e)
{
// At least, one panel
var columns = Math.Max(1, this.flowLayoutPanel1.Width / (double)PanelSize);
var rows = Math.Max(1, this.flowLayoutPanel1.Height / (double)PanelSize);
var panelsCount = this.flowLayoutPanel1.Controls.Count;
var requiredPanelsCount = rows * columns;
var diff = requiredPanelsCount - panelsCount;
if (diff > 0)
{
// We need more panels: create it
for (int i = 0; i < diff; i++)
{
var panel = new Panel
{
Size = new Size(PanelSize, PanelSize),
TabIndex = this.flowLayoutPanel1.Controls.Count,
BackColor = GetBackColor()
};
this.flowLayoutPanel1.Controls.Add(panel);
}
}
else
{
// Remove unneeded panels
for (int i = 0; i < diff; i++)
{
this.flowLayoutPanel1.Controls.RemoveAt(
this.flowLayoutPanel1.Controls.Count - 1);
}
}
}
I have used this method to set a color:
private Color GetBackColor()
{
var colors = new[]
{
Color.Black, Color.Red, Color.Green, Color.Blue, Color.White
};
var index = this.flowLayoutPanel1.Controls.Count % colors.Length;
return colors[index];
}
Adapt it to your needs.
If you need fill entire form, you must work with a variable PanelSize. Use a minimum and maximum size for the panels instead a fixed value.
I'm creating/removing Panels to fill entire space. If you only need fixed panels in the form, you don't need the resize event. The FlowLayoutControl do what you need.

Custom scrollbar scrolling triggers AutoScroll scrollbars

I've been using a UserControl to display a list of controls. I initially had AutoScroll enabled, and then opted to not using it. I chose against using it as it stood out and simply didn't 'look' good with the controls theme I've been using.
I took a shot at a framework called MetroFramework, and I've opted to use the MetroScrollBar scrollbar control for a vertical scrollbar.
I've fully disabled AutoScroll, and I then decided to implement the Scrollbar. I simply did this by:
scbMain.Scroll += (sender, e) => { VerticalScroll.Value = scbMain.Value; };
(where scbMain is the Scrollbar I'm discussing)
This works, but not as expected. As soon as I scroll, I get a crazy flickering effect from the default scrollbar, as shown here. A longer list has the same effect, but more pronounced.
I've attempted to hide the existing scrollbars:
VerticalScroll.Visible = false;
HorizontalScroll.Visible = false;
VerticalScroll.Enabled = false;
HorizontalScroll.Enabled = false;
This has had no effect on fixing my issue.
It should be noted: My scrollbar is docked to the right and there're no other container controls within the UserControl.
Ok. Problem solved. The issue was in this line of code:
scbMain.Scroll += (sender, e) => { ----> /*(Here*/ VerticalScroll.Value = scbMain.Value; <---- };
You are actully setting the scroll value of your user control, basically you tell the system to invoke the autoscroll property to set the value!
The correct way is to NOT autoscroll the user control but to scroll a container inside eg a panel. So add a panel to your user control. You are going to scroll the panel and all the controls inside it (in this example i will add the button).
this.btnExample.Location = new System.Drawing.Point(62, 0);
this.btnExample.Name = "btnExample";
this.btnExample.Size = new System.Drawing.Size(75, 390);
this.btnExample.TabIndex = 1;
this.btnExample.Text = "Out of Bounds";
this.btnExample.UseVisualStyleBackColor = true;
this.panel1.Controls.Add(this.btnExample);
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(270, 391); //the width must fit inside your user control and the height was arbitrary
this.panel1.TabIndex = 2;
this.Controls.Add(this.panel1);
this.Controls.Add(this.scbMain);
this.Name = "CtrlScroll";
this.Size = new System.Drawing.Size(474, 300);
The scrolling:
public CtrlScroll() {
InitializeComponent();
scbMain.Scroll += ( sender, e ) => {
//Normally the if statement whouldn't be needed but the metro srollbar
//has a weird behaviour when the scroll value becomes max
if( scbMain.Value > panel1.Height - this.Height ) {
panel1.Top = -( panel1.Height - this.Height );
}
else {
panel1.Top = -scbMain.Value;
};
};
int maxVertical = panel1.Height;
// SmallChange is typically 1%.
int smallChangeVertical = Math.Max( (int)( maxVertical / 100 ), 1 );
// LargeChange is one page.
int largeChangeVertical = this.Height;
scbMain.Minimum = 0;
scbMain.Maximum = maxVertical;
scbMain.SmallChange = smallChangeVertical;
scbMain.LargeChange = largeChangeVertical;
}

Size adjustments for Panel control in windows forms

I have a Panel control on my winform which will display multiple panels inside that. For each inner panel I am setting its height. But some has less content to display some has more.
Panel hrvPanel = new Panel();
ArrayList hrvColl = pnlColl ; //Panel collection list gets from a Method
if(hrvColl.Count == 0)
return;
int splits = 0;
for(int p= hrvColl.Count-1;p>=0;p--)
{
Panel hrv = hrvColl[p] as Panel;
hrv.Height = 150;
hrvPanel.Controls.Add(hrv);
//Adding splliter
if(splits < hrvColl.Count - 1)
{
Splitter splitGrid = new Splitter();
splitGrid.Dock = DockStyle.Top;
hrvPanel.Controls.Add(splitGrid);
splits++;
}
}
hrvPanel.Dock = DockStyle.Top;
How to adjust the height of each inner panel based on its content size? I tried setting hrv.AutoSize to true,then I can see only the last panel And hrv.Dock = Top but the result is same.
If the outer Panel has Autosize = true you will be able to see all inner Panels. Promise.
If you don't, you have got some settings wrong. Make sure no unwanted settings of Dock and Anchor are used in the inner Panels.
It is also very simple to write code to find out the maximum of Top + Height over all inner Panels:
int max = 0;
foreach (Control ctl in panelOuter.Controls)
if (ctl.Top + ctl.Height > max) max = ctl.Top + ctl.Height;
panelOuter.Height = max + 3; // add the default margin!
This may be useful if you only want to set the Height and leave the Width as it is..other than that: The AutoSize property will do its job!
This is where WPF overcomes Winform, you probably can't do this automatically in Winforms. But you may have a work around like this-
Create an extended panel class that should know its preferred height
class ExPanel : Panel
{
public int PreferredHeight
{
get;
private set;
}
public ExPanel(int preferredHeight)
: base()
{
PreferredHeight = preferredHeight;
}
}
and then you can use this class as-
ExPanel hrvPanel = new ExPanel(150);
System.Collections.ArrayList hrvColl = pnlColl; //Panel collection list gets from a Method
if (hrvColl.Count == 0)
return;
int splits = 0;
for (int p = hrvColl.Count - 1; p >= 0; p--)
{
ExPanel hrv = hrvColl[p] as ExPanel;
hrv.Height = hrv.PreferredHeight;
hrvPanel.Controls.Add(hrv);
//Adding splliter
if (splits < hrvColl.Count - 1)
{
Splitter splitGrid = new Splitter();
splitGrid.Dock = DockStyle.Top;
hrvPanel.Controls.Add(splitGrid);
splits++;
}
}
hrvPanel.Dock = DockStyle.Top;
it's just an workaround to achieve your target, if you don't want to manage the height for your every panel.

c# Relative position of elements in Windows Form

I try to create simple app with 2 columns using SpliterContainer and control panel with buttons. And I would like that on every screen it will look good. That's why I decided to use relative position of elements.
I read documentation and different forums, but I get something strange. Second column of splitter doesn't appear at all.
Please, can you help me find the reason of that problem?
private void Form1_Load(object sender, EventArgs e)
{
WindowState = FormWindowState.Maximized;
int screenWidth = Screen.PrimaryScreen.Bounds.Width;
int screenHeight = Screen.PrimaryScreen.Bounds.Height;
//set form size
this.Size = new Size(screenWidth, screenHeight);
//set button panel size
const double percentOfHeightPanel = 0.05;
int heightOfPanelButton = Convert.ToInt32(screenHeight * percentOfHeightPanel);
this.panel_button.Size = new System.Drawing.Size(screenWidth, heightOfPanelButton);
this.panel_button.Location = new Point(0, 0);
//set splitContainer size
int widthOfContainer = Convert.ToInt32(0.5 * screenWidth);
int heightOfContainers = Convert.ToInt32(screenHeight * (0.95));
splitContainer1.Panel1.MinimumSize = new Size(widthOfContainer, heightOfContainers);
splitContainer1.Panel2.MinimumSize = new Size(widthOfContainer, heightOfContainers);
splitContainer1.Location = new Point(0, heightOfPanelButton);
//this.splitContainer1.Panel2MinSize = screenWidth - widthOfContainer;
//set textBox size
this.textBox1.Multiline = true;
this.textBox1.Location = new Point(0, heightOfPanelButton);
this.textBox1.MinimumSize = new System.Drawing.Size(widthOfContainer, heightOfContainers);
this.textBox2.Multiline = true;
this.textBox2.Location = new Point(widthOfContainer, heightOfPanelButton);
this.textBox1.MinimumSize = new System.Drawing.Size(widthOfContainer, heightOfContainers);
}
If you want two have two splitter panels of the same size set
splitContainer1.SplitterDistance =
(splitContainer1.Width - splitContainer1.SplitterWidth) / 2;
Then set
splitContainer1.IsSplitterFixed = true;
You can set these two properties manually at design time. The user will then not be able to resize the panels and the panels will automatically resize to be of same size.
Consider using a TableLayoutPanel instead.
If further, the two sides should look the same, place your controls on a UserControl and place two instances of them into the two panels with a docked property set to Fill.

Windows forms - weird auto scroll behaviour

I got a problem in regards to autoscrolling of a system.windows.forms.panel. I have a panel that i fill with checkboxes, and if the height requirement of the total amount of checkboxes exceeds the height of the panel it should add a vertical scrollbar. My problem is that it is handles the vertical scrollbar as intended, but it also display a horizontal scrollbar wich is not needed. I adjust the width of the panel by adding System.Windows.Forms.SystemInformation.VerticalScrollBarWidth to the panel width.
int prevMainTop = 0;
int maxWidth = 0;
foreach (List<String> arr in folderArr)
{
if (arr[0].Length * 7 > maxWidth) { maxWidth = arr[0].Length * 7; }
}
foreach (List<String> arr in folderArr)
{
CheckBox cb = new CheckBox();
cb.BackColor = Color.Chocolate;
cb.Checked = true;
cb.AutoSize = false;
cb.Width = maxWidth;
cb.Name = arr[0];
cb.Text = arr[0];
cb.Tag = arr[1];
cb.Top = prevMainTop;
prevMainTop = prevMainTop + 25;
this.mainPanel.Controls.Add(cb);
}
this.mainPanel.Width = maxWidth + System.Windows.Forms.SystemInformation.VerticalScrollBarWidth;
Image showing the unwanted added space to the right of the checkboxes, color added to control background to illustrate the size of the control.
Check the AutoScrollMargin and AutoScrollMinSize properites of the panel. AutoScrollMargin should be (0,0) and you may need to also set AutoScrollMinSize to the maxWidth value.

Categories