この記事では、子コントロールを含む自動スクロール可能な Panel コントロールをクリアしてから再描画するときに発生する問題の回避策について説明します。
元の製品バージョン: Visual Basic .NET
元の KB 番号: 829417
症状
Microsoft Windows フォーム アプリケーションで、子コントロールを含む自動スクロール可能な Panel コントロールをクリアしてから再描画した場合、スクロール位置は維持されません。
原因
場合によっては、Panel コントロールの内容をクリアしてから、Panel コントロールの内容を再描画する必要があります。 たとえば、自動スクロール可能な Panel コントロールに特定の順序を持つコントロールのコレクションが含まれている場合は、これを行う必要があります。 通常、これらのコントロールはユーザー コントロールです。
ただし、アプリケーションは Panel コントロールの AutoScrollPosition プロパティの値を格納しません。 したがって、Panel コントロールの内容が再描画されるときに、スクロール位置は維持されません。
対処法
この動作を回避するには、 System.Drawing.Point 構造体を使用して、Panel コントロールの AutoScrollPosition プロパティの値を格納します。
Panel コントロールが再描画されたら、AutoScrollPosition構造体の新しいインスタンスを使用して、System.Drawing.Point プロパティの値を取得できます。
Panel.AutoScrollPosition.X プロパティの get メソッドと、Panel.AutoScrollPosition.Y プロパティの get メソッドは負の値を返します。 ただし、正の値が必要です。
Math.Abs関数を使用すると、次のコード行のように、Panel.AutoScrollPosition.X プロパティと Panel.AutoScrollPosition.Y プロパティから正の値を取得できます。
Visual Basic .NET または Visual Basic 2005 コード
Panel1.AutoScrollPosition = New Point(Math.Abs(Panel1.AutoScrollPosition.X), Math.Abs(CurrentPoint.Y))
Visual C# .NET Visual C# 2005 コード
panel1.AutoScrollPosition = new Point(Math.Abs(panel1.AutoScrollPosition.X), Math.Abs(CurrentPoint.Y));
サンプル アプリケーション
サンプル アプリケーションでこの回避策を使用するには、次の手順に従います。
[ スタート] をクリックし、[ プログラム] をポイントし、 Microsoft Visual Studio .NET をポイントして、[ Microsoft Visual Studio .NET ] または [ Microsoft Visual Studio 2005] をクリックします。
[ファイル] メニューの [新規作成] をポイントし、 [プロジェクト] をクリックします。 [新しいプロジェクト] ダイアログ ボックスが表示されます。
[ プロジェクトの種類] で、[ Visual Basic プロジェクト ] をクリックするか、[ Visual C# プロジェクト] をクリックします。
注
Visual Studio 2005 で、[ Visual C#] をクリックします。
[テンプレート] の [Windows アプリケーション] をクリックします。
[ 名前 ] ボックスに「 SampleWinApp」と入力し、[OK] をクリック します。 既定では、Form1 という名前のフォームが作成されます。
Form1 フォームに Button コントロールと Panel コントロールを追加します。
注
Panel コントロール内に Button コントロールを挿入しないでください。
Panel コントロールを右クリックし、[プロパティ] をクリックします。
Auto-Scroll プロパティを True に設定します。
Form1.vb ファイルで、
EndClass ステートメントの前に次のコードを追加します。Visual Basic .NET または Visual Basic 2005 コード
Private count As Integer Private arrayctl As New ArrayList Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim newtxt As New TextBox newtxt.Text = count count += 1 arrayctl.Add(newtxt) DrawControls() End Sub Private Sub DrawControls() Dim txt As TextBox Dim CurrentPoint As System.Drawing.Point CurrentPoint = Panel1.AutoScrollPosition() Dim i As Integer = 0 Panel1.Controls.Clear() Panel1.SuspendLayout() For Each txt In arrayctl Panel1.Controls.Add(txt) txt.Width = Panel1.ClientRectangle.Width txt.Top = i i += txt.Height Next Panel1.ResumeLayout() Panel1.AutoScrollPosition = New Point(Math.Abs(Panel1.AutoScrollPosition.X), Math.Abs(CurrentPoint.Y)) End SubVisual C# .NET または Visual C# 2005 コード
private int count; private ArrayList arrayctl = new ArrayList(); private void button1_Click(object sender, System.EventArgs e) { TextBox newtxt = new TextBox(); newtxt.Text = count.ToString(); count++; arrayctl.Add(newtxt); DrawControls(); } private void DrawControls() { System.Drawing.Point CurrentPoint; CurrentPoint = panel1.AutoScrollPosition; int i = 0; panel1.Controls.Clear(); panel1.SuspendLayout(); foreach (TextBox txt in arrayctl) { panel1.Controls.Add(txt); txt.Width = panel1.ClientRectangle.Width; txt.Top = i; i += txt.Height; } panel1.ResumeLayout(); panel1.AutoScrollPosition = new Point(Math.Abs(panel1.AutoScrollPosition.X), Math.Abs(CurrentPoint.Y)); }[デバッグ] メニューの [開始] をクリックします。
Form1 フォームで、 Button1 を繰り返しクリックして、スクロール バーを Panel コントロールに表示します。
注
スクロール位置は Panel コントロールで維持されます。