2016-03-03 3 views
1

У меня проблема. У меня есть таблицаLayoutPanel с 2 строками и 2 колонками. Первый colum пуст, а во втором - что-то. Я знаю, что обнаружил ячейку, на которую была нажата кнопка, но я не знаю, как я могу заполнить эту клетку с щелчком красным цветом. Некоторые предложения? Вот мой код:Как заполнить ячейку цветом после щелчка мыши?

private void tableLayoutPanel1_MouseClick(object sender, MouseEventArgs e) 
    { 
     int row = 0; 
     int verticalOffset = 0; 
     foreach (int h in tableLayoutPanel1.GetRowHeights()) 
     { 
      int column = 0; 
      int horizontalOffset = 0; 
      foreach (int w in tableLayoutPanel1.GetColumnWidths()) 
      { 
       Rectangle rectangle = new Rectangle(horizontalOffset, verticalOffset, w, h); 
       if (rectangle.Contains(e.Location)) 
       { 
        MessageBox.Show(String.Format("row {0}, column {1} was clicked", row, column)); 

        return; 
       } 
       horizontalOffset += w; 
       column++; 
      } 
      verticalOffset += h; 
      row++; 
     } 
    } 
+0

Да, я использую winforms – Miloss

+0

Вот хороший старт по покраске конкретной ячейки. Однако это вызвано событием рисования, поэтому нам придется расширить его для работы с щелчком ячейки .. [Переполнение стека] (http://stackoverflow.com/questions/14877012/changing-cell-colours-of-a -tablelayoutpanel-by-variables-while-runtime) –

+0

[Вот еще одна ссылка] (http://stackoverflow.com/questions/35404110/mouse-move-on-a-cell-of-my-tablelayoutpanel/35410059?s = 3 | 2.0026 # 35410059) вы можете найти полезным – TaW

ответ

1

Использование List<T> для отслеживания клеток уже перешедших:

List<Point> clickedCells = new List<Point>(); 

..you может добавить тот, который вы нашли в списке:

if (rectangle.Contains(e.Location)) 
    { 
     // * 
     Point cell = new Point(column, row); 
     if (!clickedCells.Contains(cell)) clickedCells.Add(cell); 
     // ** 
     tableLayoutPanel1.Invalidate(); 
     return; 
    } 

Чтобы выключить и снова включить цвет при повторном нажатии, вы можете добавить здесь пункт else (**):

  else clickedCells.Remove(cell); 

и если только когда-либо один элемент должен быть окрашен либо использовать только одну точку или просто очистить список здесь (*)

 clickedCells.Clear(); 

Invalidating TLP вызовет CellPaint событие, где обрабатывается список:

private void tableLayoutPanel1_CellPaint(object sender, TableLayoutCellPaintEventArgs e) 
{ 
    if (clickedCells.Contains(new Point(e.Column,e.Row))) 
     e.Graphics.FillRectangle(Brushes.Red, e.CellBounds); 
} 

Обратите внимание: Points Я использую не местоположения пикселей, а координаты ячейки!

+0

спасибо @TaW, он отлично работает. – Miloss

1

Итак, следующий код будет работать, но мне это не особенно нравится. В частности, я предполагаю, что существует более грациозный метод запуска события рисования и передачи аргументов указанному событию. Есть сообщения, основанные на событии CellPaint, но я не знаю, как его запускать. Так ..

public partial class Form1 : Form 
{ 
    Rectangle clicked = new Rectangle(); 
    bool wasClick = false; 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void tableLayoutPanel1_MouseClick(object sender, MouseEventArgs e) 
    { 
     int row = 0; 
     int verticalOffset = 0; 
     int clickx = e.X; 
     int clicky = e.Y; 
     foreach (int h in tableLayoutPanel1.GetRowHeights()) 
     { 
      int column = 0; 
      int horizontalOffset = 0; 
      foreach (int w in tableLayoutPanel1.GetColumnWidths()) 
      { 
       Rectangle rectangle = new Rectangle(horizontalOffset, verticalOffset, w, h); 
       if (rectangle.Contains(e.Location)) 
       { 
        MessageBox.Show(String.Format("row {0}, column {1} was clicked", row, column)); 
        clicked = rectangle; 
        wasClick = true; 
        tableLayoutPanel1.Invalidate(rectangle); 
        return; 
       } 
       horizontalOffset += w; 
       column++; 
      } 
      verticalOffset += h; 
      row++; 
     } 
    } 

    private void tableLayoutPanel1_Paint(object sender, PaintEventArgs e) 
    { 
     if (wasClick) 
     { 
      Graphics g = e.Graphics; 
      Rectangle r = clicked; 
      g.FillRectangle(Brushes.Red, r); 
      wasClick = false; 
     } 

    } 
} 

Предостережение в том, что при нажатии на красную клетку, он остается красным, так что вам нужно будет добавить обнаружение в отношении того, что клетки красные/не красные. Опять же, у кого-то еще может быть более элегантное решение, чем это, так что следите.

+1

спасибо! он тоже работает! – Miloss

+0

Я собирался удалить, но пошел вперед и оставил это. Я бы определенно согласился с другим решением. По какой-то причине я не смог получить событие CellPaint, чтобы вызвать вызов Invalidate, возможно, потому, что я передавал ему прямоугольник, если мне нужно было догадаться. –