スクロール位置は、Windows フォーム アプリケーションの自動スクロール可能なパネル コントロールでは維持されません
この記事では、子コントロールを含む自動スクロール可能な 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 メソッドと プロパティの get メソッドは負の値を Panel.AutoScrollPosition.Y
返します。 ただし、正の値が必要です。 関数をMath.Abs
使用すると、次のコード行のように、 プロパティと Panel.AutoScrollPosition.Y
プロパティからPanel.AutoScrollPosition.X
正の値を取得できます。
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 コントロールを挿入しないでください。
[パネル] コントロールを右クリックし、[プロパティ] をクリックします。
[自動スクロール] プロパティを True に設定します。
Form1.vb ファイルで、Class ステートメントの前に次のコードを
End
追加します。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 コントロールに表示します。
注:
スクロール位置は、Panel コントロールで維持されます。
関連情報
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示