У меня есть TableLayoutPanel
с полосой прокрутки (потому что общая высота элементов управления больше, чем высота TableLayoutPanel
). Я пытаюсь прокручивать программно в следующую/предыдущую строку с помощью кнопок PageUp- и PageDown-Keys.TableLayoutPanel может только найти элементы управления по точкам, которые были в видимой области при запуске
Прокрутка работает, но только до тех пор, пока я хочу прокрутить до элемента управления, который был уже в видимой области, когда программа запустилась. Когда я пытаюсь получить Control дальше вниз (который тем временем вошел в видимую область), tlp.GetChildAtPoint(new Point(1, tlp.AutoScrollPosition.Y * -1 + 2))
возвращает null
.
Может кто-нибудь, пожалуйста, помогите мне решить эту проблему?
Примечание: Я нашел обходное решение (см. Мой ответ), но я, конечно, открыт для других решений.
код, чтобы воспроизвести проблему:
public class FormTLPTest : Form
{
TableLayoutPanel tlp;
public FormTLPTest()
{
Height = 200;
Width = 200;
KeyPreview = true;
tlp = new TableLayoutPanel();
tlp.Dock = DockStyle.Fill;
tlp.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single;
tlp.AutoScroll = false;
tlp.VerticalScroll.Visible = true;
tlp.HorizontalScroll.Visible = false;
tlp.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 40));
Controls.Add(tlp);
tlp.SuspendLayout();
for (int i = 0; i < 20; i++)
{
Label lb2 = new Label();
lb2.Margin = new Padding(0);
lb2.Dock = DockStyle.Fill;
lb2.BackColor = Color.White;
lb2.Text = "Line " + i;
tlp.Controls.Add(lb2, 0, i);
tlp.RowStyles.Add(new RowStyle(SizeType.Absolute, 18));
tlp.RowCount++;
}
tlp.ResumeLayout();
tlp.AutoScroll = true;
KeyDown += FormTLPTest_KeyDown;
}
private void FormTLPTest_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.PageUp || e.KeyCode == Keys.PageDown || e.KeyCode == Keys.Next)
{
Control currentTopControl = tlp.GetChildAtPoint(new Point(1, tlp.AutoScrollPosition.Y * -1 + 2));
int currentRow = 0;
if (currentTopControl != null)
currentRow = tlp.GetPositionFromControl(currentTopControl).Row;
int nextRow = -1;
if (e.KeyCode == Keys.PageUp)
nextRow = currentRow - 1;
else
nextRow = currentRow + 1;
if (nextRow < 0 || nextRow > tlp.RowCount - 1)
return;
Control nextTopControl = tlp.GetControlFromPosition(0, nextRow);
tlp.AutoScrollPosition = nextTopControl.Location;
}
}
}
Это является очень распространенной ошибкой использовать TLP для осуществления контроля сетки. Это не было сделано для этого, его единственная задача - обеспечить автоматическую компоновку. Если DataGridView вас не устраивает, тогда отправляйтесь за покупками, у каждого поставщика компонентов есть сетка wiz-bang. –