碎片化渲染动态TableLayoutPanel WF
Fragmented rendering dynamic TableLayoutPanel WF
我创建了一个 class 来设计动态 TableLayoutPanel,但在呈现期间 table 表现不佳。这是 class:
using System.Drawing;
using System.Windows.Forms;
using System.Collections.Generic;
namespace office_software.Table {
class CalibrationTable : TableLayoutPanel {
private readonly string[] header;
private readonly List<Row> data;
public CalibrationTable(TableLayoutPanel parent, string[] header, List<Row> data) {
this.header = header;
this.data = data;
parent.SuspendLayout();
TableLayoutPanel child = TableConstruction();
if (parent.GetControlFromPosition(0, 1) != null) parent.Controls.Remove(parent.GetControlFromPosition(0, 1));
parent.Controls.Add(child, 0, 1);
parent.ResumeLayout(true);
}
private void CreateHeader(TableLayoutPanel parent) {
for (int i = 0; i < header.Length; i++) parent.Controls.Add(new TableLable(FontStyle.Bold, header[i], 9.75F), i, 0);
}
private void CreateBody(TableLayoutPanel parent) {
int j = 0;
foreach (Row row in data) {
for (int i = 0; i < row.values.Count; i++) {
parent.Controls.Add(new TableLable(FontStyle.Regular, row.values[i], 9.75F), i, j + 1);
}
j++;
}
}
private TableLayoutPanel TableConstruction() {
TableLayoutPanel table = new TableLayoutPanel {
AutoSize = true,
AutoScroll = true,
};
table.SuspendLayout();
if (data?.Count > 0) {
table.RowCount = data.Count + 1;
table.ColumnCount = header.Length;
table.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single;
table.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
for (int i = 0; i < table.ColumnCount; i++) table.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, (100 / table.ColumnCount)));
for (int i = 0; i < table.RowCount; i++) table.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F));
CreateHeader(table);
CreateBody(table);
}
else {
table.RowCount = 1;
table.ColumnCount = 1;
table.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
table.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
table.RowStyles.Add(new RowStyle(SizeType.Absolute, 50F));
table.Controls.Add(new TableLable(FontStyle.Bold, "NESSUN ELEMENTO TROVATO", 15F), 0, 0);
}
table.ResumeLayout();
return table;
}
}
}
这是 table 渲染过程中发生的情况。这种情况持续几秒钟。 “加载”后,table 会正常显示。
更新
这是class TableLable
:
using System.Drawing;
using System.Windows.Forms;
namespace office_software.Table {
class TableLabel : Label {
public TableLabel(FontStyle style, string text, float size) {
Text = text;
AutoSize = true;
Anchor = AnchorStyles.None;
TextAlign = ContentAlignment.MiddleCenter;
Font = new Font("Microsoft Sans Serif", size, style, GraphicsUnit.Point, 0);
}
}
为了完整起见,这是表单组件层次结构。我在 condainerPanel
内的 (col = 0, row = 1)
位置插入动态 table
设置 DoubleBuffered = true;
似乎解决了调整大小缓慢的问题:
class CalibrationTable : TableLayoutPanel {
public class Row {
public List<String> values;
}
class TableLabel : Label {
public TableLabel(FontStyle style, string text, float size) {
Text = text;
AutoSize = true;
Anchor = AnchorStyles.None;
TextAlign = ContentAlignment.MiddleCenter;
Font = new System.Drawing.Font("Microsoft Sans Serif", size, style, GraphicsUnit.Point, 0);
}
}
private readonly string[] header;
private readonly List<Row> data;
public CalibrationTable(String[] header, List<Row> data)
: base() {
this.header = header;
this.data = data;
this.AutoSize = true;
this.AutoScroll = true;
this.Dock = DockStyle.Fill;
this.DoubleBuffered = true; // this line is very important for speed
TableConstruction(this);
}
private static void CreateHeader(CalibrationTable table) {
String[] header = table.header;
for (int i = 0; i < header.Length; i++) table.Controls.Add(new TableLabel(FontStyle.Bold, header[i], 9.75F), i, 0);
}
private static void CreateBody(CalibrationTable table) {
List<Row> data = table.data;
int j = 0;
foreach (Row row in data) {
for (int i = 0; i < row.values.Count; i++) {
table.Controls.Add(new TableLabel(FontStyle.Regular, row.values[i], 9.75F), i, j + 1);
}
j++;
}
}
private static void TableConstruction(CalibrationTable table) {
table.SuspendLayout();
if (table.data.Count > 0) {
table.RowCount = table.data.Count + 1;
table.ColumnCount = table.header.Length;
table.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single;
//table.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
for (int i = 0; i < table.ColumnCount; i++) table.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, (100 / table.ColumnCount)));
for (int i = 0; i < table.RowCount; i++) table.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F));
CreateHeader(table);
CreateBody(table);
}
else {
table.RowCount = 1;
table.ColumnCount = 1;
table.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
table.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
table.RowStyles.Add(new RowStyle(SizeType.Absolute, 50F));
table.Controls.Add(new TableLabel(FontStyle.Bold, "NESSUN ELEMENTO TROVATO", 15F), 0, 0);
}
table.ResumeLayout();
}
}
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form fff = new Form();
fff.Size = new Size(900, 800);
fff.StartPosition = FormStartPosition.CenterScreen;
String[] headers = "A,B,C,D,E,F,G,H,I,J".Split(',');
List<CalibrationTable.Row> data = new List<CalibrationTable.Row>();
int k = 0;
for (int i = 0; i < 50; i++) {
List<String> list = new List<String>();
data.Add(new CalibrationTable.Row { values = list });
for (int j = 0; j < headers.Length; j++) {
list.Add(k.ToString());
k++;
}
}
CalibrationTable ct = new CalibrationTable(headers, data);
fff.Controls.Add(ct);
Application.Run(fff);
}
我创建了一个 class 来设计动态 TableLayoutPanel,但在呈现期间 table 表现不佳。这是 class:
using System.Drawing;
using System.Windows.Forms;
using System.Collections.Generic;
namespace office_software.Table {
class CalibrationTable : TableLayoutPanel {
private readonly string[] header;
private readonly List<Row> data;
public CalibrationTable(TableLayoutPanel parent, string[] header, List<Row> data) {
this.header = header;
this.data = data;
parent.SuspendLayout();
TableLayoutPanel child = TableConstruction();
if (parent.GetControlFromPosition(0, 1) != null) parent.Controls.Remove(parent.GetControlFromPosition(0, 1));
parent.Controls.Add(child, 0, 1);
parent.ResumeLayout(true);
}
private void CreateHeader(TableLayoutPanel parent) {
for (int i = 0; i < header.Length; i++) parent.Controls.Add(new TableLable(FontStyle.Bold, header[i], 9.75F), i, 0);
}
private void CreateBody(TableLayoutPanel parent) {
int j = 0;
foreach (Row row in data) {
for (int i = 0; i < row.values.Count; i++) {
parent.Controls.Add(new TableLable(FontStyle.Regular, row.values[i], 9.75F), i, j + 1);
}
j++;
}
}
private TableLayoutPanel TableConstruction() {
TableLayoutPanel table = new TableLayoutPanel {
AutoSize = true,
AutoScroll = true,
};
table.SuspendLayout();
if (data?.Count > 0) {
table.RowCount = data.Count + 1;
table.ColumnCount = header.Length;
table.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single;
table.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
for (int i = 0; i < table.ColumnCount; i++) table.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, (100 / table.ColumnCount)));
for (int i = 0; i < table.RowCount; i++) table.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F));
CreateHeader(table);
CreateBody(table);
}
else {
table.RowCount = 1;
table.ColumnCount = 1;
table.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
table.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
table.RowStyles.Add(new RowStyle(SizeType.Absolute, 50F));
table.Controls.Add(new TableLable(FontStyle.Bold, "NESSUN ELEMENTO TROVATO", 15F), 0, 0);
}
table.ResumeLayout();
return table;
}
}
}
这是 table 渲染过程中发生的情况。这种情况持续几秒钟。 “加载”后,table 会正常显示。
更新
这是class TableLable
:
using System.Drawing;
using System.Windows.Forms;
namespace office_software.Table {
class TableLabel : Label {
public TableLabel(FontStyle style, string text, float size) {
Text = text;
AutoSize = true;
Anchor = AnchorStyles.None;
TextAlign = ContentAlignment.MiddleCenter;
Font = new Font("Microsoft Sans Serif", size, style, GraphicsUnit.Point, 0);
}
}
为了完整起见,这是表单组件层次结构。我在 condainerPanel
内的 (col = 0, row = 1)
设置 DoubleBuffered = true;
似乎解决了调整大小缓慢的问题:
class CalibrationTable : TableLayoutPanel {
public class Row {
public List<String> values;
}
class TableLabel : Label {
public TableLabel(FontStyle style, string text, float size) {
Text = text;
AutoSize = true;
Anchor = AnchorStyles.None;
TextAlign = ContentAlignment.MiddleCenter;
Font = new System.Drawing.Font("Microsoft Sans Serif", size, style, GraphicsUnit.Point, 0);
}
}
private readonly string[] header;
private readonly List<Row> data;
public CalibrationTable(String[] header, List<Row> data)
: base() {
this.header = header;
this.data = data;
this.AutoSize = true;
this.AutoScroll = true;
this.Dock = DockStyle.Fill;
this.DoubleBuffered = true; // this line is very important for speed
TableConstruction(this);
}
private static void CreateHeader(CalibrationTable table) {
String[] header = table.header;
for (int i = 0; i < header.Length; i++) table.Controls.Add(new TableLabel(FontStyle.Bold, header[i], 9.75F), i, 0);
}
private static void CreateBody(CalibrationTable table) {
List<Row> data = table.data;
int j = 0;
foreach (Row row in data) {
for (int i = 0; i < row.values.Count; i++) {
table.Controls.Add(new TableLabel(FontStyle.Regular, row.values[i], 9.75F), i, j + 1);
}
j++;
}
}
private static void TableConstruction(CalibrationTable table) {
table.SuspendLayout();
if (table.data.Count > 0) {
table.RowCount = table.data.Count + 1;
table.ColumnCount = table.header.Length;
table.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single;
//table.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
for (int i = 0; i < table.ColumnCount; i++) table.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, (100 / table.ColumnCount)));
for (int i = 0; i < table.RowCount; i++) table.RowStyles.Add(new RowStyle(SizeType.Absolute, 40F));
CreateHeader(table);
CreateBody(table);
}
else {
table.RowCount = 1;
table.ColumnCount = 1;
table.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
table.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
table.RowStyles.Add(new RowStyle(SizeType.Absolute, 50F));
table.Controls.Add(new TableLabel(FontStyle.Bold, "NESSUN ELEMENTO TROVATO", 15F), 0, 0);
}
table.ResumeLayout();
}
}
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form fff = new Form();
fff.Size = new Size(900, 800);
fff.StartPosition = FormStartPosition.CenterScreen;
String[] headers = "A,B,C,D,E,F,G,H,I,J".Split(',');
List<CalibrationTable.Row> data = new List<CalibrationTable.Row>();
int k = 0;
for (int i = 0; i < 50; i++) {
List<String> list = new List<String>();
data.Add(new CalibrationTable.Row { values = list });
for (int j = 0; j < headers.Length; j++) {
list.Add(k.ToString());
k++;
}
}
CalibrationTable ct = new CalibrationTable(headers, data);
fff.Controls.Add(ct);
Application.Run(fff);
}