2016-05-19 14 views
0

TableLayoutPanelはスクロールバー付きです(コントロールの高さの合計がTableLayoutPanelの高さよりも大きいため)。 PageUp-とPageDown-Keysを使って、プログラムで次/前の行にスクロールしようとしています。TableLayoutPanelは、起動時に可視領域にあるコントロールのみを見つけることができます

スクロールは機能しますが、プログラムの開始時に既に表示されているコントロールにスクロールしたい場合に限ります。 コントロールをさらにダウンさせようとすると(その間に可視領域に入った)、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; 
     } 
    } 
} 
+0


KeyDown -listenerを変更しました。そのために作られたのではなく、その唯一の仕事は自​​動レイアウトを提供することです。 DataGridViewがあなたに合っていない場合、買い物をしてみると、すべてのコンポーネントベンダーはwiz-bangグリッドを持っています。 –

答えて

0

私はGetChildAtPoint -methodを避けて解決策を見つけました。最初の表示列を取得するために、最初の列のすべてのコントロールの位置をチェックします。

また、.AutoScrollPosition = ...を最後のコントロールへスクロールしてから、目的のコントロール(コントロールを可視領域の上部にしたい)に置き換える必要がありました。グリッドコントロールを実装するためにTLPを使用することは非常によくある間違いである

private void FormTLPTest_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.KeyCode == Keys.PageUp || e.KeyCode == Keys.PageDown || e.KeyCode == Keys.Next) 
    { 
     int currentRow = 0; 
     for (int y=0;y<tlp.RowCount;y++) 
     { 
      Control c = tlp.GetControlFromPosition(0, y); 
      if (c.Location.Y >= 0) 
      { 
       currentRow = y; 
       break; 
      } 
     } 

     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.ScrollControlIntoView(tlp.GetControlFromPosition(0, tlp.RowCount - 1)); 
     tlp.ScrollControlIntoView(nextTopControl); 
    } 
} 
関連する問題