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.
Related
I have a TableLayoutPanel, ug_degrees, with 3 columns and 1 row. Each cell gets dynamically populated with another TableLayoutPanel, degreePanel, containing 1 label and 1 textbox.
I need to get my layout to look something like this:
Right now my layout looks like this:
I'm at a loss for why I have those giant gaps between the cells, and why the row will not expand to fill its contents (a label & a textbox). I have tried to set the whole TableLayoutPanel's autosize property to true, but the columns get resized, even if I set only the rows' sizetype to autosize as well.
The properties behind the table shown are default. All non-default properties are customized in C# below.
// Dynamically load undergraduate degrees
int row = 0;
for (int i = 0; i < degrees.undergraduate.Count; i++) {
// Create and populate panel for each degree
TableLayoutPanel degreePanel = new TableLayoutPanel();
degreePanel.ColumnCount = 1;
degreePanel.RowCount = 2;
degreePanel.AutoSize = true;
foreach (RowStyle style in degreePanel.RowStyles) {
style.SizeType = SizeType.AutoSize;
}
degreePanel.BorderStyle = BorderStyle.FixedSingle;
//degreePanel.Margin = new Padding(0);
Label degTitle = new Label();
degTitle.Text = degrees.undergraduate[i].title;
degTitle.Dock = DockStyle.Fill;
TextBox degDesc = new TextBox();
degDesc.ReadOnly = true;
degDesc.Multiline = true;
degDesc.Dock = DockStyle.Fill;
degDesc.Text = degrees.undergraduate[i].description;
SizeF size = degDesc.CreateGraphics()
.MeasureString(degDesc.Text,
degDesc.Font,
degDesc.Width,
new StringFormat(0));
degDesc.Height = (int)size.Height;
degreePanel.Controls.Add(degTitle, 0, 0);
degreePanel.Controls.Add(degDesc, 0, 1);
ug_degrees.Controls.Add(degreePanel, i, row);
// Resize rows and columns (only after adding controls)
foreach (RowStyle style in ug_degrees.RowStyles) {
style.SizeType = SizeType.AutoSize;
}
// Jump to next row if current row is full
if ((i+1) % 3 == 0) {
row++;
}
Add degreePanel.Dock = DockStyle.Fill
I have the problem that the text inside my panel gets cut of strangely. The panel is located inside a textbox. But even if I replace the textbox by a flowlayoutpanel, I have the same issue.
Code:
List<string> list = datenbank.FerienAuswahl(monat, jahr);
int i = 0;
//Create Panel
try
{
//Fill Panel
do
{
Label panel = new Label();
panel.Name = "panel" + i;
panel.Height = 30;
panel.Width = 400;
panel.AutoSize = false;
panel.TextAlign = ContentAlignment.MiddleCenter;
panel.ForeColor = Color.Black;
panel.Text = list[i];
Label ferien = new Label();
panel.Controls.Add(ferien);
tbFerien.Controls.Add(panel);
i++;
} while (i < list.Count);
}
catch { }
Result:
I have already tried to change the width of the panel. But as result I only get a messed up alignment of the text.
The only settings of the textbox I have changed are these:
Multiline: True
TextAlign: Center
Size: 359; 125
Does Someone know what else I could try ?
These lines worry me:
Label panel = new Label();
Label ferien = new Label();
panel.Controls.Add(ferien);
tbFerien.Controls.Add(panel);
It seems to me you are adding one label to another. That's not good. Use a Panel or TableLayoutPanel instead of the actual panel and make sure you have your positioning good.
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.
I have a datagridview in winform and would like to do two things. Resize the datagrid so that all columns are showen (no scrolls) based on the datagrid size resize the width of the winform.
tried the code below but it doesn't work*
int width = 0;
foreach (DataGridViewColumn col in information.Columns)
{
width += col.Width;
}
width += information.RowHeadersWidth;
information.ClientSize = new Size(width + 100,height);
Simple order of operations:
Set the AutoSizeColumnMode property of the DataGridView to AllCells.
Add the Width property of all the columns plus some slack for extra width from borders on the control, etc. (Maybe plus 2)
Set the Width property of the DataGridView to the width you calculated.
Set the form's Width to the Width of the DataGridView.
Up to you to actually code it.
EDIT: I am in front of a compiler now so I put this together:
Go into Visual Studio. Start a new Project. Don't put anything onto the form in the designer. Simply use this code in the initializer.
public Form1()
{
InitializeComponent();
// Create a DataGridView with 5 Columns
// Each column is going to sized at 100 pixels wide which is default
// Once filled, we will resize the form to fit the control
DataGridView dataGridView1 = new DataGridView();
for (int i = 0; i < 5; i++)
{
DataGridViewTextBoxColumn col = new DataGridViewTextBoxColumn();
dataGridView1.Columns.Add(col);
}
dataGridView1.Location = new Point(0, 0);
// Add the DataGridView to the form
this.Controls.Add(dataGridView1);
// Step 2:
// Figure out the width of the DataGridView columns
int width = 0;
foreach (DataGridViewColumn col in dataGridView1.Columns)
width += col.Width;
width += dataGridView1.RowHeadersWidth;
// Step 3:
// Change the width of the DataGridView to match the column widths
// I add 2 pixels to account for the control's borders
dataGridView1.Width = width + 2;
// Step 4:
// Now make the form's width equal to the conbtrol's width
// I add 16 to account for the form's boarders
this.Width = dataGridView1.Width + 16;
}
This code creates a DataGridView with five columns and then sizes the control and the form exactly as you requested. I followed the exact steps I outlined above (except for step 1 because I don't have any data in my columns).
This code works. So if yours is NOT working, there must be something else silly that you have going on and I can't help you.
Hello I found out how to get this working using the following code below. information is the datagrid and this is the form.
int width = 0;
this.information.RowHeadersVisible = false;
for (int i = 0; i < information.Columns.Count; i++)
width += information.Columns[i].GetPreferredWidth(DataGridViewAutoSizeColumnMode.AllCells, true);
int rows = 0;
this.information.RowHeadersVisible = false;
for (int i = 0; i < information.Rows.Count; i++)
rows += information.Rows[i].GetPreferredHeight(i, DataGridViewAutoSizeRowMode.AllCells, true);
information.Size = new Size(width +20, rows+50);
this.Width = width + 50;
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.