この記事では、子コントロールを含む自動スクロール可能な Panel コントロールをクリアしてから再描画するときに発生する問題の回避策について説明します。
元の製品バージョン: Visual Basic .NET
元の KB 番号: 829417
現象
Microsoft Windows フォーム アプリケーションで、子コントロールを含む自動スクロール可能な Panel コントロールをクリアしてから再描画した場合、スクロール位置は維持されません。
原因
場合によっては、Panel コントロールの内容をクリアしてから、Panel コントロールの内容を再描画する必要があります。 たとえば、自動スクロール可能な Panel コントロールに特定の順序を持つコントロールのコレクションが含まれている場合は、これを行う必要があります。 通常、これらのコントロールはユーザー コントロールです。
ただし、アプリケーションは Panel コントロールの AutoScrollPosition
プロパティの値を格納しません。 したがって、Panel コントロールの内容が再描画されるときに、スクロール位置は維持されません。
回避策
この動作を回避するには、 System.Drawing.Point
構造体を使用して、Panel コントロールの AutoScrollPosition
プロパティの値を格納します。
Panel コントロールが再描画されたら、System.Drawing.Point
構造体の新しいインスタンスを使用して、AutoScrollPosition
プロパティの値を取得できます。
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));
サンプル アプリケーション
サンプル アプリケーションでこの回避策を使用するには、次の手順に従います。
[Start] をクリックし、Programs をポイントし、Microsoft Visual Studio .NET をポイントして、[Microsoft Visual Studio .NET または Microsoft Visual Studio 2005 をクリックします。
[ファイル] メニューの [新規作成] をポイントし、 [プロジェクト] をクリックします。 [新しいプロジェクト] ダイアログ ボックスが表示されます。
[プロジェクトの種類で、Visual Basic Projectsをクリックするか、[C# プロジェクト表示] をクリック。
Note
Visual Studio 2005 で、[ Visual C#] をクリックします。
[ Templatesで、 Windows アプリケーションをクリックします。
[名 ボックスに「SampleWinApp」と入力し、[
OK] をクリック 。 既定では、Form1 という名前のフォームが作成されます。Form1 フォームに Button コントロールと Panel コントロールを追加します。
Note
Panel コントロール内に Button コントロールを挿入しないでください。
Panel コントロールを右クリックし、Properties をクリックします。
Auto-Scroll プロパティを True に設定します。
Form1.vb ファイルで、
End
Class ステートメントの前に次のコードを追加します。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 Sub
Visual 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 コントロールに表示します。
Note
スクロール位置は Panel コントロールで維持されます。