2013-10-24 3 views
1

Я пишу программу решения Picross в winforms, где сетка должна быть изменчиваема, чтобы можно было решить разные размеры. Я использовал 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

У вас может быть новый класс ярлыков, который наследует ярлык и имеет все ваши общие свойства, предварительно заполненные. – tinstaafl

ответ

2

Чтобы максимизировать эффективность с помощью решения на основе TableLayoutPanel, избегайте воссоздания всех элементов управления Label при изменении размера. Вы можете реализовать схему добавления/удаления элементов управления при изменении размера; это будет работать быстрее, но сложнее проектировать.

Некоторые предложения по повышению эффективности Вашего воссоздают подход:

  • избежать повторения арифметику: вычислить i * newSize + j только один раз и присвоить результат локальной переменной.
  • Использовать метод TableLayoutPanel.Controls.AddRange вместо TableLayoutPanel.Controls.Add. Это может предотвратить временный «замороженный» пользовательский интерфейс.
  • Попробуйте установить TableLayoutPanel.DoubleBuffered = true. Целью этого является предотвращение мерцания при изменении значимой области пользовательского интерфейса, но это также может ускорить процесс.
+1

Это исправлено! Изменение размера от 5x5 до 25x25 и обратно было занято около 15 секунд до этого, и теперь это до простых долей секунды. Большинство из них можно отнести к настройке на doubleBuffered, но остальное было полезно. Большое спасибо :) –

0

Это проблема GDI, если я понимаю вашу проблему. Начиная с Windows Vista модель драйвера видеокарты обеспечивает аппаратное ускорение только небольшого подмножества операций GDI. Таким образом, большинство операций GDI при изменении размера окна выполняется программно.

Как я знаю, единственным решением является WPF.

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 секунды.

Смежные вопросы