2013-03-16 4 views
1

У меня есть TableLayoutPanel, и я хочу добавить элемент управления в ячейку, на которую я нажимаю.Как определить, какая ячейка нажата в TableLayoutPanel?

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

Как определить, на какую ячейку нажали?

ответ

9

Вы можете использовать GetColumnWidths и GetRowHeights методы для расчета ячейки строки и столбца индекса:

Point? GetRowColIndex(TableLayoutPanel tlp, Point point) 
{ 
    if (point.X > tlp.Width || point.Y > tlp.Height) 
     return null; 

    int w = tlp.Width; 
    int h = tlp.Height; 
    int[] widths = tlp.GetColumnWidths(); 

    int i; 
    for (i = widths.Length - 1; i >= 0 && point.X < w; i--) 
     w -= widths[i]; 
    int col = i + 1; 

    int[] heights = tlp.GetRowHeights(); 
    for (i = heights.Length - 1; i >= 0 && point.Y < h; i--) 
     h -= heights[i]; 

    int row = i + 1; 

    return new Point(col, row); 
} 

Использование:

private void tableLayoutPanel1_Click(object sender, EventArgs e) 
{ 
    var cellPos = GetRowColIndex(
     tableLayoutPanel1, 
     tableLayoutPanel1.PointToClient(Cursor.Position)); 
} 

Но обратите внимание, что событие щелчка только возникает, если ячейка не уже содержат элемент управления.

+0

Я не могу найти эти методы :( Я использую .netframe work 4.5 –

+0

@AymanSharaf Какие методы? Мой код не компилятор? Каково ваше сообщение об ошибке? –

+0

Я не могу найти GetColumnWidths и GetRowHeights –

3

Это работает для меня:

public TableLayoutPanel tableLayoutPanel { get; set; } 

private void Form_Load(object sender, EventArgs e) 
{ 
    foreach (Panel space in this.tableLayoutPanel.Controls) 
    { 
     space.MouseClick += new MouseEventHandler(clickOnSpace); 
    } 
} 

public void clickOnSpace(object sender, MouseEventArgs e) 
{ 

    MessageBox.Show("Cell chosen: (" + 
        tableLayoutPanel.GetRow((Panel)sender) + ", " + 
        tableLayoutPanel.GetColumn((Panel)sender) + ")"); 
} 

Обратите внимание, что мой TableLayoutPanel объявлен во всем мире, так что я могу просто использовать его без необходимости передать его в каждой функции. Кроме того, как tableLayoutPanel, так и каждая панель внутри него создаются полностью программно в другом месте (моя форма [дизайн] полностью пуста).

+0

Perfect. Это работает для меня. –

1

Мой ответ основан на ответе @Mohammad Dehghan «s выше, но имеет несколько преимуществ:

  • Теперь учитывающую вертикальной прокрутки
  • Столбцы в правильном порядке (начинается в i=0 вместо i=length), то есть столбцы разной ширины или высоты, обрабатываются в правильном порядке

Вот обновленная версия кода:

public Point? GetIndex(TableLayoutPanel tlp, Point point) 
{ 
    // Method adapted from: stackoverflow.com/a/15449969 
    if (point.X > tlp.Width || point.Y > tlp.Height) 
     return null; 

    int w = 0, h = 0; 
    int[] widths = tlp.GetColumnWidths(), heights = tlp.GetRowHeights(); 

    int i; 
    for (i = 0; i < widths.Length && point.X > w; i++) 
    { 
     w += widths[i]; 
    } 
    int col = i - 1; 

    for (i = 0; i < heights.Length && point.Y + tlp.VerticalScroll.Value > h; i++) 
    { 
     h += heights[i]; 
    } 
    int row = i - 1; 

    return new Point(col, row); 
} 
Смежные вопросы