2012-03-19 1 views
0

У меня есть пользовательский элемент управления WinForms, и я пытаюсь сделать 15 строк из 15 квадратов. Если размер изменения управления, то квадраты должны получить меньше, но все равно есть 15 строк из 15 квадратов, как этот шаблон:Создание квадратной сетки 15x15 в пользовательском элементе управления

OOOOOOOOOOOOOOO 
OOOOOOOOOOOOOOO 
OOOOOOOOOOOOOOO 
OOOOOOOOOOOOOOO 
OOOOOOOOOOOOOOO 
OOOOOOOOOOOOOOO 
OOOOOOOOOOOOOOO 
OOOOOOOOOOOOOOO 
OOOOOOOOOOOOOOO 
OOOOOOOOOOOOOOO 
OOOOOOOOOOOOOOO 
OOOOOOOOOOOOOOO 
OOOOOOOOOOOOOOO 
OOOOOOOOOOOOOOO 
OOOOOOOOOOOOOOO 

Я пытаюсь использовать ClientSize.Width и ClientSize.Height разделить на 15, но его не выходит точно вправо. Любая помощь с этим алгоритмом была бы оценена!

Это, кстати, на C#.

Вот код, у меня есть:

графика г = e.Graphics;

 g.DrawRectangle(Pens.Black, 0, 0, ClientSize.Width - 1, ClientSize.Height - 1); 

     if (ClientSize.Width > ClientSize.Height) 
     { 
      int ndx = (int)Math.Ceiling(ClientSize.Height/15f); 
      for (int x = 0; x < ClientSize.Width; x += ndx) 
      { 
       for (int y=0 ; y<ClientSize.Height; y+=ndx) 
       { 
        g.DrawLine(Pens.Black, x, y, x + ndx, y); 
        g.DrawLine(Pens.Black, x, y, x, y + ndx); 
       } 
      } 
     } 
     else 
     { 
      int ndx = (int)Math.Ceiling(ClientSize.Width/15f); 
      for (int x = 0; x < ClientSize.Width; x += ndx) 
      { 
       for (int y = 0; y < ClientSize.Height; y += ndx) 
       { 
        g.DrawLine(Pens.Black, x, y, x + ndx, y); 
        g.DrawLine(Pens.Black, x, y, x, y + ndx); 
       } 
      } 
     } 
     g.Dispose(); 
+0

Ну, что значит «не выходит точно вправо»? (* Полезно * описание проблемы * и * код, пожалуйста) –

+0

«Не получается точно вправо» означает, что при изменении размера пользовательского элемента в конце, как правило, есть дополнительная строка или отсутствие линии в конце – Icemanind

+0

Если деление не является совершенным будет небольшая разница. Однако, похоже, это вызвано ошибкой округления. Я бы рекомендовал всегда стрелять по * нижней стороне, округляя вниз, а затем используя это (интегральное) значение как множитель в цикле. Помните, что каждая ячейка сетки должна включать в себя нижний правый край (при рисовании), а верхний левый край всей сетки должен учитываться при начальных вычислениях общего размера. –

ответ

1

Часть проблемы заключается в том, что ваша сетка будет соответствовать только тогда, когда ширина и высота контейнера точно делятся на 15. Попробуйте округлить.

const int ColumnCount = 15; 
const int RowCount = 15; 
int cellwidth = (int)Math.Floor(ClientSize.Width/ColumnCount); 
int cellheight = (int)Math.Floor(ClientSize.Height/RowCount ); 

После того, как вы нарисуете свою сетку, явным образом отключите область, расположенную за последней строкой и столбцом. У вас будет толстая черная рамка, но она четко определит сетку 15x15.

Если вы хотите, чтобы избежать черной каймой, заставляют ClientSize.Width и .Height, чтобы быть кратные ColumnCount и RowCount соответственно.

+0

Могу ли я перехватить событие изменения размера элемента управления и «привязать» размер до кратного 15? Если возможно, это решение может работать – Icemanind

+0

Я был под впечатлением 'int/int -> int', всегда усекающийся (округление к нулю) ... –

+0

@icemanind, да. Просто добавьте обработчик событий для «Me.Resize» или «Me.SizeChanged» и установите для него «ClientSize». При изменении размера вы можете получить некоторое графическое мерцание. Я не понял, как этого избежать. –

1

Поскольку у вас идеальный квадрат, это намного проще; если контроль шире, чем высокий, разделите высоту на 15 и используйте ее как сторону каждого квадрата. Если он выше ширины, разделите ширину на 15 и используйте это как сторону каждого квадрата.

+0

Я только что написал код. Я делаю то, что вы сказали, я думаю, но все еще не так. Подобно тому, как внизу будет дополнительная линия. – Icemanind

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