我正在winforms中编写一个Picross求解程序,其中网格可以调整大小以允许解决不同的大小。我一直在使用List<System.Windows.Forms.Label>
为网格的每个方格保留一个标签,但是当我将网格大小调整为15x15以上的大小时,为了简单地调整网格大小,它往往需要几秒钟。虽然我不认为网格大小的快速切换是常见的,但我希望网格不需要花费10秒钟来填充标签。
System.Windows.Forms.TableLayoutPanel PicrossGrid;
List<System.Windows.Forms.Label> PicrossGridLabel;
private void adjustGridLabel(int newSize)
{
System.Windows.Forms.Label[] temp = new System.Windows.Forms.Label[newSize*newSize];
for (int i = 0; i < newSize; i++)
{
for (int j = 0; j < newSize; j++)
{
temp[i * newSize + j] = new System.Windows.Forms.Label();
temp[i * newSize + j].Anchor = System.Windows.Forms.AnchorStyles.None;
temp[i * newSize + j].AutoSize = true;
temp[i * newSize + j].Font = new System.Drawing.Font("Microsoft Sans Serif", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
temp[i * newSize + j].Location = new System.Drawing.Point(i, j);
temp[i * newSize + j].Name = "PicrossGridLabelC" + (i + 1) + "R" + (j + 1);
temp[i * newSize + j].Size = new System.Drawing.Size(24, 30);
temp[i * newSize + j].TabIndex = (i * 5) + j;
temp[i * newSize + j].Text = "X";
temp[i * newSize + j].TextAlign = System.Drawing.ContentAlignment.TopCenter;
PicrossGrid.Controls.Add(temp[i * newSize + j], i, j);
}
}
PicrossGridLabel = temp.ToList();
}
我还在函数中放置this.SuspendLayout();
之前调用它以防止绘图减速,但它仍然非常慢。有没有更好的方法来解决这个问题,或者我正在制定可能的疏忽?
答案 0 :(得分:2)
要使用基于TableLayoutPanel
的解决方案最大限度地提高效率,请避免在大小更改时重新创建所有Label
控件。你可以实现一个方案来随着大小的变化添加/删除控件;这会更快,但设计起来更困难。
提高重新创建方法效率的一些建议:
i * newSize + j
并将结果分配给局部变量。TableLayoutPanel.Controls.AddRange
方法代替TableLayoutPanel.Controls.Add
。这可能会阻止暂时“冻结”的用户界面。TableLayoutPanel.DoubleBuffered = true
。这样做的目的是在重要UI区域发生变化时防止闪烁,但也可以加快速度。答案 1 :(得分:0)
如果我理解你的问题,这就是GDI的问题。自Windows Vista以来,视频卡驱动程序模型仅提供GDI操作的一小部分硬件加速。因此,当您开始以编程方式调整窗口大小时,大多数GDI操作都会执行。
据我所知,唯一的解决方案是WPF。
答案 2 :(得分:0)
您还可以通过删除数组然后将控件集合转换为列表来节省大量时间。
System.Windows.Forms.TableLayoutPanel PicrossGrid;
List<PiCrossLabel> PicrossGridLabel;
private void adjustGridLabel(int newSize)
{
for (int i = 0; i < newSize; i++)
{
for (int j = 0; j < newSize; j++)
{
PiCrossLabel NewLabel = new PiCrossLabel();
NewLabel.Name = "PicrossGridLabelC" + (i + 1) + "R" + (j + 1);
TabIndex = (i * 5) + j;
PicrossGrid.Controls.Add(NewLabel, i, j);
}
}
PicrossGridLabel = temp.ToList();
}
public class PiCrossLabel:Label
{
public PiCrossLabel()
{
this.Anchor = System.Windows.Forms.AnchorStyles.None;
this.AutoSize = true;
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 20F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.Size = new System.Drawing.Size(24, 30);
this.Text = "X";
this.TextAlign = System.Drawing.ContentAlignment.TopCenter;
}
}
在我的系统上,20X20可以填充大约4秒钟。