Removing controls from TableLayoutPanel does not reset scrollbar
-
Dienstag, 7. September 2010 10:51
I use a table layout panel in a custom control in an application. As the app runs during the day items are added to the control and once a day I remove all Items from the table layout panel as part of a housekeeping routine.
As Items are added to the controls collection of the panel the scroll slider of the vertical scroll bar in the panel reduces in size to reflect the number of Items in the control as it should. However on removing Items from the Controls collection does not reset the scroll bar. Once emptied the next days Items are added to the controls collection and the scroll bar slider begins shrinking even further eventualy the control hangs and the app must be restarted.
for example:
on day one I add fifty items to the layout panel. Scroll bar reflects control count perfectly. Through the night all added controls are removed ready for next day.
day 2 50 more are added: but now scroll bar is sized as if there were a hundred.
this continues until the control 'breaks'.
Items are removed from the layout panel controls collection via Tablelayoutpanel.Controls.Remove(item);
item.Dispose();I hope this is clear: english is not my favourite subject!
regards
Joh.
- Verschoben CoolDadTxMVP Mittwoch, 22. August 2012 17:05 Winforms related (From:Visual C# General)
Alle Antworten
-
Montag, 22. August 2011 15:51
Hi Joh,
Given your code I could have modified it, but I decided to just write some up. Here it is:
Code:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace tester { public partial class Form1 : Form { int vPos, num; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { pnlPanel = new Panel(); pnlPanel.Size = new Size(150, 250); pnlPanel.AutoScrollMinSize = new Size(0, 0); pnlPanel.AutoScroll = true; vPos = 0; num = 0; } private void AddSomeButtons() { Button[] btns = new Button[50]; for (int i = 0; i < btns.Length; i++) { btns[i] = new Button(); btns[i].Text = "btns[" + num + "]"; pnlPanel.Controls.Add(btns[i]); btns[i].Top = vPos; vPos += 22; num++; } this.Controls.Add(pnlPanel); } private void btnAdd_Click(object sender, EventArgs e) { AddSomeButtons(); pnlPanel.Refresh(); } private void RemoveSomeButtons() { if (pnlPanel != null && pnlPanel.Controls.Count > 0) { int j = 50; for (int i = pnlPanel.Controls.Count; j > 0; i--, j--) { pnlPanel.Controls.RemoveAt(i - 1); vPos -= 22; num--; } } } private void btnRemove_Click(object sender, EventArgs e) { RemoveSomeButtons(); pnlPanel.Refresh(); } } }Pay special attention to the code in Form1_Load, and also note that I refresh the panel after I remove controls.
The form designer code:
namespace tester { partial class Form1 { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.btnAdd = new System.Windows.Forms.Button(); this.btnRemove = new System.Windows.Forms.Button(); this.SuspendLayout(); // // btnAdd // this.btnAdd.Location = new System.Drawing.Point(206, 3); this.btnAdd.Name = "btnAdd"; this.btnAdd.Size = new System.Drawing.Size(75, 23); this.btnAdd.TabIndex = 0; this.btnAdd.Text = "Add"; this.btnAdd.UseVisualStyleBackColor = true; this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click); // // btnRemove // this.btnRemove.Location = new System.Drawing.Point(206, 32); this.btnRemove.Name = "btnRemove"; this.btnRemove.Size = new System.Drawing.Size(75, 23); this.btnRemove.TabIndex = 0; this.btnRemove.Text = "Remove"; this.btnRemove.UseVisualStyleBackColor = true; this.btnRemove.Click += new System.EventHandler(this.btnRemove_Click); // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(284, 262); this.Controls.Add(this.btnRemove); this.Controls.Add(this.btnAdd); this.Name = "Form1"; this.Text = "Form1"; this.Load += new System.EventHandler(this.Form1_Load); this.ResumeLayout(false); } #endregion private System.Windows.Forms.Button btnAdd; private System.Windows.Forms.Button btnRemove; private System.Windows.Forms.Panel pnlPanel; } }When btnAdd is pressed, 50 buttons are added to the control and the scroll bar button gets smaller. When btnRemove is pressed, 50 buttons are removed and the scroll bar button gets bigger again!
Hope this helps. Kind regards,
- Als Antwort vorgeschlagen Woohoooo Montag, 22. August 2011 15:57
-
Mittwoch, 22. August 2012 02:31
i have the same problem.
i user panel replace the tablelayout.maybe this is a good solution.
-
Mittwoch, 22. August 2012 16:59
Hi,
I recently had another crack at this and found the solution:
this.tableLayoutPanel.AutoScroll = false;
this.tableLayoutPanel.AutoScroll = true;
The above two lines of code reset the scroll bar.
Thanks,
John
ltheONEl
- Als Antwort markiert ltheONEl Mittwoch, 22. August 2012 17:00
-
Sonntag, 28. Oktober 2012 22:18
Hi,
I recently had another crack at this and found the solution:
this.tableLayoutPanel.AutoScroll = false;
this.tableLayoutPanel.AutoScroll = true;
The above two lines of code reset the scroll bar.
Thanks,
John
ltheONEl
I have found that if you use this code there is a bug in tablelayoutpanel where after you toggle autoscroll like that more than once an extra horizontal bit of space ends up in the tablelayoutpanel and a horizontal scrollbar shows even if you specify for it to be disabled or invisible.
Because of this inconsistency when clearing and refilling a panel such as this at runtime I have opted to just use
tablelayoutpanel1.VerticalScroll.Value = 0
And this brings the scrollbar back to the top. I call this line of code AFTER I set my rowstyles and number of rows/columns.

