自动滚动表格布局面板中的图形故障
Graphical glitch in auto-scrolling tablelayoutpanel
我有一个动态生成的 WinForms 表单 TableLayoutPanel
。在运行时,我添加或删除行,因此我设置了最大大小并将其设置为自动滚动。所有的行和列都是自动调整大小的,我为垂直滚动条添加了填充,这样它就不会最终与单元格重叠(从而强制创建水平滚动条,使用(在创建表单时):
tableLayoutPanel_dataLogs.Padding = new Padding(0, 0, SystemInformation.VerticalScrollBarWidth, 0);
当没有足够的数据来强制自动滚动时,它看起来像这样:
问题是,当它添加自动滚动时,它引入了这个奇怪的图形故障:
故障是复选标记图像下方右侧和复选标记上方边框上的白线。我认为这一定与滚动条外观设置有关,但我不太确定是什么。有什么想法吗?
编辑:为 tableLayoutPanel
添加代码:
//
// tableLayoutPanel_dataLogs
//
this.tableLayoutPanel_dataLogs.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)));
this.tableLayoutPanel_dataLogs.AutoSize = true;
this.tableLayoutPanel_dataLogs.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.tableLayoutPanel_dataLogs.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.InsetDouble;
this.tableLayoutPanel_dataLogs.ColumnCount = 7;
this.tableLayoutPanel_dataLogs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel_dataLogs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel_dataLogs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel_dataLogs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel_dataLogs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel_dataLogs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel_dataLogs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel_dataLogs.Controls.Add(this.checkBox_getAllDataLogs, 0, 0);
this.tableLayoutPanel_dataLogs.Controls.Add(this.label1, 1, 0);
this.tableLayoutPanel_dataLogs.Controls.Add(this.label2, 3, 0);
this.tableLayoutPanel_dataLogs.Controls.Add(this.label3, 5, 0);
this.tableLayoutPanel_dataLogs.Controls.Add(this.label5, 4, 0);
this.tableLayoutPanel_dataLogs.Controls.Add(this.label4, 2, 0);
this.tableLayoutPanel_dataLogs.Controls.Add(this.pictureBox1, 6, 0);
this.tableLayoutPanel_dataLogs.Location = new System.Drawing.Point(6, 445);
this.tableLayoutPanel_dataLogs.MaximumSize = new System.Drawing.Size(600, 144);
this.tableLayoutPanel_dataLogs.MinimumSize = new System.Drawing.Size(400, 56);
this.tableLayoutPanel_dataLogs.Name = "tableLayoutPanel_dataLogs";
this.tableLayoutPanel_dataLogs.Padding = new System.Windows.Forms.Padding(0, 0, System.Windows.Forms.SystemInformation.VerticalScrollBarWidth, 0);
this.tableLayoutPanel_dataLogs.RowCount = 1;
this.tableLayoutPanel_dataLogs.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel_dataLogs.Size = new System.Drawing.Size(420, 56);
this.tableLayoutPanel_dataLogs.TabIndex = 65;
this.tableLayoutPanel_dataLogs.Visible = false;
下面是添加行的代码:
tableLayoutPanel_dataLogs.Visible = false;
tableLayoutPanel_dataLogs.SuspendLayout();
for (int i = 0; i < logCount; i++)
{
//code that generates the data to populated not shown
//...
//created currentSerial, currentDateTime, currentEntriesCount
tableLayoutPanel_dataLogs.RowCount++;
tableLayoutPanel_dataLogs.RowStyles.Add(new RowStyle(SizeType.AutoSize));
string row = (tableLayoutPanel_dataLogs.RowCount - 1).ToString("D2");
string cbName = ControlNames.checkBoxSelectedName + row;
tableLayoutPanel_dataLogs.Controls.Add(new CheckBox { Name = cbName, Text = String.Empty, Anchor = AnchorStyles.None, AutoSize = true }, 0, tableLayoutPanel_dataLogs.RowCount - 1);
CheckBox cb = this.Controls.Find(cbName, true).First() as CheckBox;
checkBoxes.Add(cb.Name,cb);
cb.CheckedChanged += new System.EventHandler(this.checkBox_getAnyDataLog_CheckedChanged);
tableLayoutPanel_dataLogs.Controls.Add(new Label() { Name = ControlNames.labelNumberName + row, Text = (tableLayoutPanel_dataLogs.RowCount - 1).ToString(), Anchor = AnchorStyles.None, Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))), AutoSize = true }, 1, tableLayoutPanel_dataLogs.RowCount - 1);
tableLayoutPanel_dataLogs.Controls.Add(new Label() { Name = ControlNames.labelSerialName + row, Text = currentSerial, Anchor = AnchorStyles.None, Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))), AutoSize = true }, 2, tableLayoutPanel_dataLogs.RowCount - 1);
tableLayoutPanel_dataLogs.Controls.Add(new Label() { Name = ControlNames.labelDateTimeName + row, Text = currentDateTime.ToString("MM/dd/yy HH:mm"), Anchor = AnchorStyles.None, Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))), AutoSize = true }, 3, tableLayoutPanel_dataLogs.RowCount - 1);
tableLayoutPanel_dataLogs.Controls.Add(new Label() { Name = ControlNames.labelEntriesName + row, Text = currentEntriesCount, Anchor = AnchorStyles.None, Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))), AutoSize = true }, 4, tableLayoutPanel_dataLogs.RowCount - 1);
string tbName = ControlNames.textBoxFileNameName + row;
tableLayoutPanel_dataLogs.Controls.Add(new TextBox() { Name = tbName, Text = String.Empty, Enabled = false, Anchor = AnchorStyles.Left, Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))), AutoSize = true }, 5, tableLayoutPanel_dataLogs.RowCount - 1);
TextBox tb = this.Controls.Find(tbName, true).First() as TextBox;
tb.TextChanged += new System.EventHandler(this.textBoxFileName_TextChanged);
tableLayoutPanel_dataLogs.Controls.Add(new PictureBox() { Name = ControlNames.pictureBoxName + row, Image = global::DataKey_Application.Properties.Resources.check_small, Text = "", Enabled = false, Visible = false, Margin = new System.Windows.Forms.Padding(0, 0, 0, 0), SizeMode = PictureBoxSizeMode.AutoSize, Anchor = AnchorStyles.Left }, 6, tableLayoutPanel_dataLogs.RowCount - 1);
}
tableLayoutPanel_dataLogs.ResumeLayout();
tableLayoutPanel_dataLogs.PerformLayout();
当出现垂直滚动时,停靠会更改 table 上的宽度。您的最小尺寸可能不允许它变小。
好的,是时候挖掘这个并回答我自己的问题了(再次)。我回到这个问题是因为我的 tableLayoutPanel
从一个长列表(例如需要自动滚动)回到一个小列表时没有正确调整大小。我从 here 的@Bioukh 那里得到了一个想法,并将 tableLayoutPanel
放到了 panel
中。该面板定义 tableLayoutPanel
的最大尺寸,它停靠在 Dock = top 内部,并且自动滚动 禁用 。就在我绘制 table 之前,我检查了它的首选高度并在 面板 上启用自动滚动(如果它太大)。当我清除 table 时,我还禁用了面板上的自动滚动。这确保了 table 在应该显示时显示滚动条(没有图形故障),并且当 table 较小时面板滚动条消失。
绘制后 table:
tableLayoutPanel_dataLogs.ResumeLayout();
tableLayoutPanel_dataLogs.PerformLayout();
if (tableLayoutPanel_dataLogs.GetPreferredSize(new Size()).Height > panel1.Size.Height)
panel1.AutoScroll = true;
tableLayoutPanel_dataLogs.Visible = true;
正在清除 table:
tableLayoutPanel_dataLogs.SuspendLayout();
TableLayoutControlCollection controls = tableLayoutPanel_dataLogs.Controls;
for (int i = controls.Count - 1; i > 0; i--)
{
if (tableLayoutPanel_dataLogs.GetCellPosition(controls[i]).Row != 0)
{
Control control = controls[i];
if (control.Name.Contains(ControlNames.checkBoxSelectedName)) ((CheckBox)control).CheckedChanged -= new System.EventHandler(this.checkBox_getAnyDataLog_CheckedChanged);
else if (control.Name.Contains(ControlNames.textBoxFileNameName)) ((TextBox)control).TextChanged -= new System.EventHandler(this.textBoxFileName_TextChanged);
controls.Remove(control);
control.Dispose();
}
}
while (tableLayoutPanel_dataLogs.RowCount > 1)
{
int row = tableLayoutPanel_dataLogs.RowCount - 1;
tableLayoutPanel_dataLogs.RowStyles.RemoveAt(row);
tableLayoutPanel_dataLogs.RowCount--;
}
tableLayoutPanel_dataLogs.Size = new System.Drawing.Size(420, 56);
tableLayoutPanel_dataLogs.Visible = false;
tableLayoutPanel_dataLogs.ResumeLayout();
tableLayoutPanel_dataLogs.PerformLayout();
panel1.AutoScroll = false;
panel1.PerformLayout();
checkBoxes.Clear();
你为什么不使用数据网格。它很简单,滚动时不会出现故障,因为它是实时更新的。而且,它的功能比tablelayoutpanel
还要多
我有一个动态生成的 WinForms 表单 TableLayoutPanel
。在运行时,我添加或删除行,因此我设置了最大大小并将其设置为自动滚动。所有的行和列都是自动调整大小的,我为垂直滚动条添加了填充,这样它就不会最终与单元格重叠(从而强制创建水平滚动条,使用(在创建表单时):
tableLayoutPanel_dataLogs.Padding = new Padding(0, 0, SystemInformation.VerticalScrollBarWidth, 0);
当没有足够的数据来强制自动滚动时,它看起来像这样:
问题是,当它添加自动滚动时,它引入了这个奇怪的图形故障:
故障是复选标记图像下方右侧和复选标记上方边框上的白线。我认为这一定与滚动条外观设置有关,但我不太确定是什么。有什么想法吗?
编辑:为 tableLayoutPanel
添加代码:
//
// tableLayoutPanel_dataLogs
//
this.tableLayoutPanel_dataLogs.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)));
this.tableLayoutPanel_dataLogs.AutoSize = true;
this.tableLayoutPanel_dataLogs.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.tableLayoutPanel_dataLogs.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.InsetDouble;
this.tableLayoutPanel_dataLogs.ColumnCount = 7;
this.tableLayoutPanel_dataLogs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel_dataLogs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel_dataLogs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel_dataLogs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel_dataLogs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel_dataLogs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel_dataLogs.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel_dataLogs.Controls.Add(this.checkBox_getAllDataLogs, 0, 0);
this.tableLayoutPanel_dataLogs.Controls.Add(this.label1, 1, 0);
this.tableLayoutPanel_dataLogs.Controls.Add(this.label2, 3, 0);
this.tableLayoutPanel_dataLogs.Controls.Add(this.label3, 5, 0);
this.tableLayoutPanel_dataLogs.Controls.Add(this.label5, 4, 0);
this.tableLayoutPanel_dataLogs.Controls.Add(this.label4, 2, 0);
this.tableLayoutPanel_dataLogs.Controls.Add(this.pictureBox1, 6, 0);
this.tableLayoutPanel_dataLogs.Location = new System.Drawing.Point(6, 445);
this.tableLayoutPanel_dataLogs.MaximumSize = new System.Drawing.Size(600, 144);
this.tableLayoutPanel_dataLogs.MinimumSize = new System.Drawing.Size(400, 56);
this.tableLayoutPanel_dataLogs.Name = "tableLayoutPanel_dataLogs";
this.tableLayoutPanel_dataLogs.Padding = new System.Windows.Forms.Padding(0, 0, System.Windows.Forms.SystemInformation.VerticalScrollBarWidth, 0);
this.tableLayoutPanel_dataLogs.RowCount = 1;
this.tableLayoutPanel_dataLogs.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel_dataLogs.Size = new System.Drawing.Size(420, 56);
this.tableLayoutPanel_dataLogs.TabIndex = 65;
this.tableLayoutPanel_dataLogs.Visible = false;
下面是添加行的代码:
tableLayoutPanel_dataLogs.Visible = false;
tableLayoutPanel_dataLogs.SuspendLayout();
for (int i = 0; i < logCount; i++)
{
//code that generates the data to populated not shown
//...
//created currentSerial, currentDateTime, currentEntriesCount
tableLayoutPanel_dataLogs.RowCount++;
tableLayoutPanel_dataLogs.RowStyles.Add(new RowStyle(SizeType.AutoSize));
string row = (tableLayoutPanel_dataLogs.RowCount - 1).ToString("D2");
string cbName = ControlNames.checkBoxSelectedName + row;
tableLayoutPanel_dataLogs.Controls.Add(new CheckBox { Name = cbName, Text = String.Empty, Anchor = AnchorStyles.None, AutoSize = true }, 0, tableLayoutPanel_dataLogs.RowCount - 1);
CheckBox cb = this.Controls.Find(cbName, true).First() as CheckBox;
checkBoxes.Add(cb.Name,cb);
cb.CheckedChanged += new System.EventHandler(this.checkBox_getAnyDataLog_CheckedChanged);
tableLayoutPanel_dataLogs.Controls.Add(new Label() { Name = ControlNames.labelNumberName + row, Text = (tableLayoutPanel_dataLogs.RowCount - 1).ToString(), Anchor = AnchorStyles.None, Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))), AutoSize = true }, 1, tableLayoutPanel_dataLogs.RowCount - 1);
tableLayoutPanel_dataLogs.Controls.Add(new Label() { Name = ControlNames.labelSerialName + row, Text = currentSerial, Anchor = AnchorStyles.None, Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))), AutoSize = true }, 2, tableLayoutPanel_dataLogs.RowCount - 1);
tableLayoutPanel_dataLogs.Controls.Add(new Label() { Name = ControlNames.labelDateTimeName + row, Text = currentDateTime.ToString("MM/dd/yy HH:mm"), Anchor = AnchorStyles.None, Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))), AutoSize = true }, 3, tableLayoutPanel_dataLogs.RowCount - 1);
tableLayoutPanel_dataLogs.Controls.Add(new Label() { Name = ControlNames.labelEntriesName + row, Text = currentEntriesCount, Anchor = AnchorStyles.None, Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))), AutoSize = true }, 4, tableLayoutPanel_dataLogs.RowCount - 1);
string tbName = ControlNames.textBoxFileNameName + row;
tableLayoutPanel_dataLogs.Controls.Add(new TextBox() { Name = tbName, Text = String.Empty, Enabled = false, Anchor = AnchorStyles.Left, Font = new System.Drawing.Font("Microsoft Sans Serif", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))), AutoSize = true }, 5, tableLayoutPanel_dataLogs.RowCount - 1);
TextBox tb = this.Controls.Find(tbName, true).First() as TextBox;
tb.TextChanged += new System.EventHandler(this.textBoxFileName_TextChanged);
tableLayoutPanel_dataLogs.Controls.Add(new PictureBox() { Name = ControlNames.pictureBoxName + row, Image = global::DataKey_Application.Properties.Resources.check_small, Text = "", Enabled = false, Visible = false, Margin = new System.Windows.Forms.Padding(0, 0, 0, 0), SizeMode = PictureBoxSizeMode.AutoSize, Anchor = AnchorStyles.Left }, 6, tableLayoutPanel_dataLogs.RowCount - 1);
}
tableLayoutPanel_dataLogs.ResumeLayout();
tableLayoutPanel_dataLogs.PerformLayout();
当出现垂直滚动时,停靠会更改 table 上的宽度。您的最小尺寸可能不允许它变小。
好的,是时候挖掘这个并回答我自己的问题了(再次)。我回到这个问题是因为我的 tableLayoutPanel
从一个长列表(例如需要自动滚动)回到一个小列表时没有正确调整大小。我从 here 的@Bioukh 那里得到了一个想法,并将 tableLayoutPanel
放到了 panel
中。该面板定义 tableLayoutPanel
的最大尺寸,它停靠在 Dock = top 内部,并且自动滚动 禁用 。就在我绘制 table 之前,我检查了它的首选高度并在 面板 上启用自动滚动(如果它太大)。当我清除 table 时,我还禁用了面板上的自动滚动。这确保了 table 在应该显示时显示滚动条(没有图形故障),并且当 table 较小时面板滚动条消失。
绘制后 table:
tableLayoutPanel_dataLogs.ResumeLayout();
tableLayoutPanel_dataLogs.PerformLayout();
if (tableLayoutPanel_dataLogs.GetPreferredSize(new Size()).Height > panel1.Size.Height)
panel1.AutoScroll = true;
tableLayoutPanel_dataLogs.Visible = true;
正在清除 table:
tableLayoutPanel_dataLogs.SuspendLayout();
TableLayoutControlCollection controls = tableLayoutPanel_dataLogs.Controls;
for (int i = controls.Count - 1; i > 0; i--)
{
if (tableLayoutPanel_dataLogs.GetCellPosition(controls[i]).Row != 0)
{
Control control = controls[i];
if (control.Name.Contains(ControlNames.checkBoxSelectedName)) ((CheckBox)control).CheckedChanged -= new System.EventHandler(this.checkBox_getAnyDataLog_CheckedChanged);
else if (control.Name.Contains(ControlNames.textBoxFileNameName)) ((TextBox)control).TextChanged -= new System.EventHandler(this.textBoxFileName_TextChanged);
controls.Remove(control);
control.Dispose();
}
}
while (tableLayoutPanel_dataLogs.RowCount > 1)
{
int row = tableLayoutPanel_dataLogs.RowCount - 1;
tableLayoutPanel_dataLogs.RowStyles.RemoveAt(row);
tableLayoutPanel_dataLogs.RowCount--;
}
tableLayoutPanel_dataLogs.Size = new System.Drawing.Size(420, 56);
tableLayoutPanel_dataLogs.Visible = false;
tableLayoutPanel_dataLogs.ResumeLayout();
tableLayoutPanel_dataLogs.PerformLayout();
panel1.AutoScroll = false;
panel1.PerformLayout();
checkBoxes.Clear();
你为什么不使用数据网格。它很简单,滚动时不会出现故障,因为它是实时更新的。而且,它的功能比tablelayoutpanel
还要多