Ich habe eine TableLayoutPanel
mit einer Bildlaufleiste (weil die Gesamthöhe der Controls größer ist als die Höhe der TableLayoutPanel
). Ich versuche, mit den PageUp- und PageDown-Keys programmgesteuert zur nächsten/vorherigen Zeile zu scrollen.TableLayoutPanel kann nur Controls by Point finden, die beim Start im sichtbaren Bereich waren
Scrollen funktioniert, aber nur so weit ich möchte zu einem Control scrollen, das bereits im sichtbaren Bereich war, als das Programm gestartet wurde. Wenn ich versuche, eine Steuerung weiter nach unten zu bringen (die inzwischen in den sichtbaren Bereich eingetreten ist), gibt tlp.GetChildAtPoint(new Point(1, tlp.AutoScrollPosition.Y * -1 + 2))
null
zurück.
Kann mir bitte jemand helfen, dieses Problem zu lösen?
Hinweis: Ich habe einen Workaround gefunden (siehe meine Antwort), aber ich bin natürlich offen für andere Lösungen.
Code, um das Problem zu reproduzieren:
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;
}
}
}
Es ist ein sehr häufiger Fehler TLP zu verwenden, um eine Gittersteuerung zu implementieren. Es wurde nicht dafür gemacht, seine einzige Aufgabe ist es, automatisches Layout bereitzustellen. Wenn DataGridView nicht zu Ihnen passt, gehen Sie einkaufen, jeder Komponentenanbieter hat ein Wiz-Bang-Grid. –