Controls have locked min. width or max size - c#

I have a form with a tableLayoutPanel. It has 1 column and 2 rows with 2 controls. A label and a listView. In design mode I cant set the label height larger than 17. And the listView I can manualy enlarge but not shrink. The controls dimensions remain larger that the form itself. So either the controls are cliped or I end up with the forms scrollbars. So why the controls autosize larger than the form? And when I run the app they dont shrink to minSize either.
//
// labelTitle
//
resources.ApplyResources(this.labelTitle, "labelTitle");
this.labelTitle.ForeColor = System.Drawing.Color.DeepSkyBlue;
this.labelTitle.Name = "labelTitle";
//
// tableLayoutPanel
//
resources.ApplyResources(this.tableLayoutPanel, "tableLayoutPanel");
this.tableLayoutPanel.Controls.Add(this.labelTitle, 0, 0);
this.tableLayoutPanel.Controls.Add(this.aListView, 0, 1);
this.tableLayoutPanel.GrowStyle = System.Windows.Forms.TableLayoutPanelGrowStyle.FixedSize;
this.tableLayoutPanel.Name = "tableLayoutPanel";
//
// aListView
//
resources.ApplyResources(this.aListView, "aListView");
this.aListView.AllowDrop = true;
this.aListView.BackColor = System.Drawing.SystemColors.Desktop;
this.aListView.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.aListView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
this.aListView.LargeImageList = this.coverImageList;
this.aListView.MultiSelect = false;
this.aListView.Name = "aListView";
this.aListView.ShowGroups = false;
this.aListView.ShowItemToolTips = true;
this.aListView.TileSize = new System.Drawing.Size(200, 200);
this.aListView.UseCompatibleStateImageBehavior = false;
this.aListView.View = System.Windows.Forms.View.Tile;
//
// form
//
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.Desktop;
this.Controls.Add(this.tableLayoutPanel);
this.Name = "Form";
this.albumsContextMenu.ResumeLayout(false);
this.tableLayoutPanel.ResumeLayout(false);
this.ResumeLayout(false);
Instead of docking the controls I anchored them. Now I can change their size in design mode if I start with the top control first.

A Label has AutoSize = true by default, which resizes the control based on content and ignores your manual settings.
Before seeing the effect of you changing the size, you must disable the AutoSize property.
label1.AutoSize = false;
label1.Height = 50;
(Note that you can set the Height first, but you won't see the effect until you disable AutoSize.)
For the second question, you'll have to elaborate on what you mean by "the listView only grows in size".

Related

User Control Not Resizing When The Window Is In Maximized State - Windows Forms C#

Lately I am working on this personal app, it's form is without border so the Exit Button, Minimize Button and Maximize button, as well as the option to resize and move the form have been custom added. The app contains several User Controls which perform different functions such as Login, a Control Panel for the app and so on. The issue here is that the User Controls, which are placed within a panel (Anchored properly, of course) in the main form are not resizing properly when the window is in a Maximized state.
To detail... the app starts at
this size and while it's manually resized in minimized state the controls have no issue inheriting it's parent's (the panel) size,
like this and this also works if the window is maximized while the control is visible, like this however if the window is already in a maximized state and I call the control with the designated button the control does not resize, it stays to it's minimum dimensions, like so.
At first I thought it may have something to do with the code that resizes the form so I removed everything and made the app with the default windows border and controls, basically set the border Property from none to sizable but that did nothing. Also I have tried accessing the User Control's parent (the panel) using this.Parent and then setting the width and height of the control with Width = this.Parent.Width and Height = this.Parent.Height but the parent returns null for some reason which I am yet to understand. Now, worth mentioning that those user controls are dynamically added (i.e Login loginForm = new Login();) to the panel every time the button is clicked and then Disposed once the control is left.
I looked all over Google for this but found nothing related and at this point I am out of options. I really want the app to be resizable and must resize properly so if anyone has any solutions I am open to anything.
Thanks anticipated.
Meanwhile, for Winforms, I may have an answer.. the key is to use the Resize event of your user control(s), see below. I tested this in Core 3.1 and Net 4.7, you can use an default designer.cs unit with an empty form. It has no issues with resize from maximized state.
My user control for the center app is named CenteredPanel and derived from Panel. Make sure you derive your user controls from Panel and call base() on the constructor, else the docking will not work properly.
Also, your question about parenting: it was not needed to use Parent below, but if you really need it, make sure you assign it !
public partial class Form1 : Form
{
private Panel panel1, panel2, panel3, panel4;
private CenteredPanel panelApp;
public Form1()
{
InitializeComponent();
this.panel1 = new System.Windows.Forms.Panel()
{ Parent = this, Dock = DockStyle.Fill };
this.panel2 = new System.Windows.Forms.Panel()
{ Parent = panel1, Dock = DockStyle.Left, Width = 120, BackColor = Color.FromArgb(60, 60, 60) };
this.panel3 = new System.Windows.Forms.Panel()
{ Parent = panel1, Dock = DockStyle.Fill };
this.panel4 = new System.Windows.Forms.Panel()
{ Parent = panel3, Dock = DockStyle.Top, Height = 60, BackColor = Color.FromArgb(60, 60, 60) };
this.panelApp = new WindowsFormsAppCore.CenteredPanel()
{ Parent = panel3, Dock = DockStyle.Fill, BackColor = Color.FromArgb(90, 90, 90) };
this.panel1.Controls.Add(this.panel3);
this.panel1.Controls.Add(this.panel2);
this.panel3.Controls.Add(this.panelApp);
this.panel3.Controls.Add(this.panel4);
this.Controls.Add(this.panel1);
}
}
public class CenteredPanel : Panel
{
Label label1, label2;
TextBox textbox1;
public CenteredPanel() : base()
{
this.Resize += new System.EventHandler(this.Resizer);
this.label1 = new System.Windows.Forms.Label()
{ Parent = this, AutoSize = true, Name = "label1", ForeColor =Color.White, Text = "Connectare Administrator" };
this.label2 = new System.Windows.Forms.Label()
{ Parent = this, AutoSize = true, Name = "label2", ForeColor = Color.White, Text = "Nume de utilizator" };
this.textbox1 = new System.Windows.Forms.TextBox()
{ Parent = this, AutoSize = true, Name = "textbox1", PasswordChar = '*', Text = "****" };
this.Controls.Add(this.label1);
this.Controls.Add(this.label2);
this.Controls.Add(this.textbox1);
}
public void Resizer(object sender, EventArgs e)
{
Point CenteringAnchor = new Point(Width / 2, Height / 2);
for (int i=0; i<Controls.Count; i++)
{
Control c = Controls[i];
// put your resizing rules here.. this is a very simple one
c.Location = new Point(CenteringAnchor.X - c.Width / 2, -40 + i * ((i == 1) ? 40 : 30) + CenteringAnchor.Y - c.Height / 2);
}
}
}

Cannot remove spacing between controls in TableLayoutPanel?

There's some spacing between the Buttons I add to my TableLayoutPanel. I removed the border in the Button and set the Margin and Padding to 0 in the Panel. But I continue getting that spacing.
tableLayoutPanel.RowCount is set to 8 and the Rows collection I've added 8 rows with Size Type Absolute.
Am I missing something? Here's the code:
private void FillSelectLayout()
{
tableLayoutPanelSelect.Controls.Clear();
tableLayoutPanelSelect.RowStyles.Clear();
tableLayoutPanelSelect.RowCount = 8;
for (int i = 0; i < 8; i++)
{
Button buttonSelector = new Button();
buttonSelector.Height = 64;
buttonSelector.Width = 100;
buttonSelector.FlatStyle = FlatStyle.Flat;
buttonSelector.FlatAppearance.BorderSize = 0;
buttonSelector.BackColor = Color.Yellow;
tableLayoutPanelSelect.Controls.Add(buttonSelector, 0, i);
}
}
Here's how it's displayed:
To remove the space between buttons in cells, it's enough to set dock property of them to fill and then remove default margins of buttons:
var b = new Button();
b.Dock = DockStyle.Fill;
b.Margin = new Padding(0);
Note:
Usually it's better to set Dock property of controls which you host in cells to Fill. This way your controls will follow TableLayouPanel sizing rules which you set for columns and rows.
TableLayoutPanel use Margin property of control to set the location of control in cell. So If you don'n want to set Dock and you prefer to set the Size manually, it's enough to set the Margin only.
I .. set the Margin and Padding to 0 in the Panel.
Why didn't you remove the Margin in the Buttons instead:
buttonSelector.Margin = new Padding(0);
MSDN:
The Margin property defines the space around the control that keeps
other controls a specified distance from the control's borders.
I faced the same problem while using different control in TableLayoutPanel
You can do this
Go to Design View
Click on the properties
GoTo Columns, When you click text box besides Columns, a button (...) appears on extreme right, click it
A pop up window appears, Select AutoSize (Instead of Absolute or Percentage).
In the same window in Show: select Rows and again select Autosize.
Click okay and you are done.

Align dynamically added controls horizontally and vertically within a control in c# winforms

I have this program that dynamically adds pictureboxes referring to the number of president in the database. How do i put them inside the groupbox and align the pictureboxes inside the groupbox? And the groupbox should stretch if the pictureboxes are many.
I have this codes now :
private void Form1_Load(object sender, EventArgs e)
{
conn.Open();
try
{
cmd = new SqlCommand("SELECT COUNT(Position) FROM TableVote WHERE Position='" + "President" + "'", conn);
Int32 PresCount = (Int32)cmd.ExecuteScalar();
TxtPresCount.Text = PresCount.ToString();
for (int i = 0; i < PresCount; ++i)
{
GroupBox PresGB = new GroupBox();
{
PresGB.Size = new Size(491, 152);
PresGB.Location = new Point(12, 12);
PresGB.Text = "President";
this.Controls.Add(PresGB);
PresGB.SendToBack();
PictureBox PresPB = new PictureBox();
PresPB.Location = new Point(80 + (150 * i) + 20, 50);
PresPB.Size = new Size(75, 75);
PresPB.BorderStyle = BorderStyle.Fixed3D;
PresPB.ImageLocation = "imgPath";
this.Controls.Add(PresPB);
PresPB.BringToFront();
};
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
conn.Close();
}
}
I would want the pictureboxes to be inside the groupbox and align it inside.
Maybe the FlowLayoutPanel control already does what you are trying to do. Just create your picture boxes and add them to a FlowLayoutPanel instead of a GroupBox.
FlowLayoutPanel automatically arranges controls in rows and/or columns depending on the value of its FlowDirection property. Set myFlowLayoutPanel.FlowDirection = FlowDirection.TopDown to get a vertical arranged list.
If you don't want multiple rows or columns set the WrapContents property to false. You can also set the AutoScroll property to true to automatically get scrollbars if the controls don't fit.
If you prefer to have the border of a GroupBox you can still put the FlowLayoutPanel into a GroupBox.
To adjust the space between the picture boxes you can use the Margin property.
This gives you a lot of control over the layout and you don't need to calculate the control positions. Also, if the size of the FlowLayoutPanel changes everything is rearranged automatically.
UPDATE:
I have a few comments on your code:
The curly braces make this look like the syntax of an object initializer - but it isn't.
GroupBox PresGB = new GroupBox(); // this line ends with a semicolon
{
// therefore this is just a block of code not related to new GroupBox()
};
You should remove the curly braces.
The creation of the group box is inside the loop. I doubt that you want a new group box for each picture box. This is the reason why you only see a single picture. Each new group box hides all the previous ones.
You add the picture boxes to the form instead of the group box.
You use "cryptic" names. PresGB and PresPB are very likely to be swapped accidentally. Abbreviations are usually a bad choice for names.
You don't need to call SendToBack or BringToFront since you don't want the controls to overlap anyway.
I don't think GroupBox is a good choice. Of course you can make it bigger if the number of pictures increases but you are limited by the screen and you don't get scollbars if the picture boxes don't fit. Use a FlowLayoutPanel. It has all the "magic" that you are looking for.
Replace your for loop with this piece of code:
var panel = new FlowLayoutPanel();
panel.SuspendLayout(); // don't calculate the layout before all picture boxes are added
panel.Size = new Size(491, 152);
panel.Location = new Point(12, 12);
panel.BorderStyle = BorderStyle.Fixed3D;
panel.FlowDirection = FlowDirection.LeftToRight;
panel.AutoScroll = true; // automatically add scrollbars if needed
panel.WrapContents = false; // all picture boxes in a single row
this.Controls.Add(panel);
for (int i = 0; i < PresCount; ++i)
{
var pictureBox = new PictureBox();
// the location is calculated by the FlowLayoutPanel
pictureBox.Size = new Size(75, 75);
pictureBox.BorderStyle = BorderStyle.FixedSingle;
pictureBox.ImageLocation = "imgPath";
panel.Controls.Add(pictureBox);
}
panel.ResumeLayout();
You can always drop a control on your form, do what you want to do then look at the designer generated code to see how the designer does it (in the "Designer.cs" file). Behind the scenes it is loading all controls and setting all properties via code.
That being said.
Keep in mind that once you put your picturebox inside the groupbox all location coordinate are in relation to the groupbox. So "0,0" is the upper-left corner of the groupbox, not the form.
To anchor your picturebox use the following code (this is just a straight copy-paste from my designer generated code, so you can clean it up a bit):
this.PresPB.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
To dock your picture box (so it fills the entire containing control):
this.PresPB.Dock = System.Windows.Forms.DockStyle.Fill;
You also need to change this line:
this.Controls.Add(PresPB);
to this:
PresGB.Controls.Add(PresPB);

When changing tab selections, child panels are not redrawn unless widnow screen is minimized, maximized or restored

I'm having an issue with a Windows Forms project. I change tabs but the change does not reflect unless I maximize,minimize,or restore the entire window. After that the newly selected tab will show it's child contents.
I've narrowed the issue down to my trying to programmatic create and name a datagridview
I can do this:
logs_datagrid.Name = "datagrid_logs";
logs_datagrid.AutoSize = true;
logs_datagrid.Dock = DockStyle.Fill;
logs_datagrid.Font = new Font("Microsoft Sans Serif", 8.25F);
logs_datagrid.DataSource = dt_logs_google;
logs_datagrid.AllowUserToAddRows = false;
logs_datagrid.BackColor = System.Drawing.Color.White;
logs_datagrid.BringToFront();
splitContainer2.Panel2.Controls.Add(logs_datagrid);
but as soon as I try to programatically apply edits to the datagridview columns the issue occurs. Just uncommenting the top line here will cause the error.
DataGridViewColumn dvg_col_1 = logs_datagrid.Columns[0];
// DataGridViewColumn dgv_col_2 = logs_datagrid.Columns[1];
// DataGridViewColumn dgv_col_3 = logs_datagrid.Columns[3];
//dgv_col_1.ReadOnly = true;
// dgv_col_1.MinimumWidth = 200;
//dgv_col_2.ReadOnly = true;
//dgv_col_2.MinimumWidth = 200;
//dgv_col_3.ReadOnly = true;
//dgv_col_3.MinimumWidth = 200;
// dgv_col_3.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
[edit] Thank you for the help!
Perhaps Update();.
(Didn't check this case, but I've seen Update(); work, when Invalidate(); didn't.)
Try this.Invalidate() of your control
http://windowsclient.net/articles/windowsformspainting.aspx

How to add scrollbar to groupbox? C# 4.0

So... did someone know how to make it?...
In a panel is easy, because we can set the "AutoScroll" property, to true... but groupbox doesn't have it.
Anyways... exists some way for it?, thanks in advance ;-).
Quite simple... Add a panel inside a group box.
Declare Group box object and Panel object which will contain the scroll bar by default and some of my Check box objects;I read somewhere that Group box's don't have scroll bar for aesthetic reasons(i hope it's not true, why not let the user make that call). Solution is simple, once you know that you will create a panel that will lay on top of your group box just to get your scroll bar.
private System.Windows.Forms.GroupBox grpDR;//GROUPBOX IN WHICH PANEL WILL OVERLAY
private System.Windows.Forms.Panel grpScrlDR;//PANEL WHICH WILL HAVE SCROLL BAR AND CONTAIN CHECK BOXES
private System.Windows.Forms.CheckBox chkDr2;
private System.Windows.Forms.CheckBox chkDr1;
private void InitializeComponent()
{
this.grpScrlDR = new System.Windows.Forms.Panel();
this.chkDr2 = new System.Windows.Forms.CheckBox();
this.chkDr1 = new System.Windows.Forms.CheckBox();
this.grpDR = new System.Windows.Forms.GroupBox();
this.grpScrlDR.SuspendLayout();
this.grpDR.SuspendLayout();
//
// grpScrlDR
// PANEL DETAILS ADDING CHECKBOX CONTROLS AND ENABLING AUTO SCROLL
this.grpScrlDR.AutoScroll = true;
this.grpScrlDR.Controls.Add(this.chkDr2);
this.grpScrlDR.Controls.Add(this.chkDr1);
this.grpScrlDR.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpScrlDR.Location = new System.Drawing.Point(5, 336);
this.grpScrlDR.Name = "grpScrlDR";
this.grpScrlDR.Size = new System.Drawing.Size(175, 230);
this.grpScrlDR.TabIndex = 0;
//
// chkDr2
//
this.chkDr2.AutoSize = true;`
this.chkDr2.Location = new System.Drawing.Point(13, 45);
this.chkDr2.Name = "chkDr2";
this.chkDr2.Size = new System.Drawing.Size(54, 20);
this.chkDr2.TabIndex = 1;
this.chkDr2.Text = "Permit#";
this.chkDr2.UseVisualStyleBackColor = true;
this.chkDr2.CheckedChanged += new System.EventHandler(this.chkDr_CheckedChanged);
//
// chkDr1
//
this.chkDr1.AutoSize = true;
this.chkDr1.Checked = true;
this.chkDr1.CheckState = System.Windows.Forms.CheckState.Checked;
this.chkDr1.Location = new System.Drawing.Point(13, 22);
this.chkDr1.Name = "chkDr1";
this.chkDr1.Size = new System.Drawing.Size(54, 20);
this.chkDr1.TabIndex = 0;
this.chkDr1.Text = "Account";
this.chkDr1.UseVisualStyleBackColor = true;
this.chkDr1.CheckedChanged += new System.EventHandler(this.chkDr_CheckedChanged);
//
// grpDR
// GROUP BOX DETAILS - GROUP BOX IS ADDING PANEL CONTROLS
this.grpDR.Controls.Add(this.grpScrlDR);
this.grpDR.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.grpDR.Location = new System.Drawing.Point(5, 336);
this.grpDR.Name = "grpDR";
this.grpDR.Size = new System.Drawing.Size(175, 230);
this.grpDR.TabIndex = 46;
this.grpDR.TabStop = false;
this.grpDR.Text = "Report by";
this.grpDR.Visible = false;
}
The GroupBox cannot display a scroll bar. If you need a control similar to a GroupBox that can contain a scroll bar, see the Panel control
Read This Article - Find (The GroupBox cannot display a scroll bar) Text
If you need to add a panel inside of your GroupBox, Dock a Panel inside of the GroupBox and set the AutoScroll property on the docked Panel to true. You can then place any controls you need inside of the GroupBox on the Panel, which will scroll when necessary.
If you don't like the way that looks as you stated above, then you have two possible options:
There may be a way to hack (more like "abuse" in this situation) the GroupBox control by making calls into the native Win32 API to add a scrollbar. I rarely use native calls on managed controls, but I've done this in situations where, for instance, I need to disable the scroll bar on a ListView as ListView doesn't expose this property. Below I expose the native Win32 function for use in C#, just call SetScrollBarVisible to enable or disable the scrollbar as needed from your code (I have not tested this on a GroupBox):
If aesthetics is THAT important to you (not a bad thing, user experience is greatly underappreciated in many areas of the application development world) and adding a scroll bar to the GroupBox doesn't work/look good to you, you will need to find another solution. I would imagine the best solution would be to make your own control from the ground up that meets your expectations (or modify the scrollbar itself, no idea how to do this), though this is can be a lot more work than it might be worth.
Here is how I expose and call the Win32 function SetScrollBar from my C# code (sorry, the DllImport won't format as a code block for some reason):
[DllImport ("user32")]
private static extern long ShowScrollBar (long hwnd , long wBar, long bShow);
long SB_HORZ = 0;
long SB_VERT = 1;
long SB_BOTH = 3;
private static void SetScrollBarVisible (Control control, long sb, bool enable)
{
if (control != null) return;
if (enable)
ShowScrollBar(control.Handle.ToInt64(), sb, 1);
else
ShowScrollBar(control.Handle.ToInt64(), sb, 0);
}
To do this you would have to add 1 panel to the groupbox and set the autoscroll property to true.
Then you would add a second panel which would be large then the first panel.
On this second panel (StringPanel in the beleow code) you would add controls.
System.Windows.Forms.GroupBox StringsGroup;
System.Windows.Forms.Panel StingPanel;
System.Windows.Forms.Panel StringPanel2;
StringsGroup = new System.Windows.Forms.GroupBox();
StingPanel = new System.Windows.Forms.Panel();
StringPanel2 = new System.Windows.Forms.Panel();
//Add your controls to StringPanel
StingPanel.Size = new System.Drawing.Size(300, 800);
StringPanel2.Size = new System.Drawing.Size(325, 345);
StringPanel2.AutoScroll = true;
this.StringPanel2.Controls.Add(StingPanel);
this.StringsGroup.Controls.Add(this.StringPanel2);
Horizontal Scroll Bar Tip
If you have a panel where all the controls contained within it are anchored to the top (so that they are centered) you will never see the horizontal scroll bar. You need to have at least one control that is anchored left & top that disappears when the panel is too small to show it in order for the horizontal scroll bar to appear. I put a label with hidden text on the panel to accomplish this.
This little tidbit took me quite a while to discover! Hope it's helpful!
If you dont want scrollbars, but want your GroupBox to grow, you can edit these below properties from the Layout section as shown below.
AutoSize = true;
AutoSizeMode = GrowOnly;

Categories

Resources