|
■No86667 (魔界の仮面弁士 さん) に返信
ありがとうございます。
提示頂いたコードで期待通りの動作をしました。
> AutoScroll = True では駄目なのですか?
特に駄目と云う事ではないですけど、コードから動的にコントロールを追加、削除を
繰り返すような実装になっている場合、自動でスクロールバーが出たり消えたりする為、
スクロールバーの有無でコントロールの幅が変わるので(縦スクロールバーの場合)、
それが嫌なケースもあります。
特に今回、何かアプリを作成しているわけではないので、具体的にといわれると困りますが...
> それと、キーボード(ScrollUp/ScrollDown/上矢印/下矢印/Tab/Shift+Tab)による操作や、
マウスホイールと上下キーには以下のコードで対応しました。
> フォームのリサイズ(高さ変更)への追従、
フォームのリサイズ(高さ変更)への追従はちょっと意味がわかりませんでした。
リサイズ時に問題がでそうな事項があれば、教えてください。
> スクロール領域外のコントロールにフォーカスがあることを許容するかどうかなども検討しておく必要がありそうです。
これはケースバイケースで対応します。
> その仕様だと、最後のボタンを表示しきれない気もしますが、
> それはとりあえず後で考えるとして。
これは、質問した後、気付きました。
これについては、VScrollBarのMaximumプロパティを変更する事で、対応しました。
もし何か、お気づきの点があれば、ご指摘ください。
Option Strict On
Public Class Form1
Private _max As Integer = 100
Private WithEvents FlowLayoutPanel1 As New FlowLayoutPanel() With {.AutoScroll = False, .Dock = DockStyle.Fill, .WrapContents = False, .FlowDirection = FlowDirection.TopDown}
Private WithEvents _VScrollBar As New VScrollBar() With {.Maximum = _max, .Minimum = 0, .LargeChange = 10, .SmallChange = 1, .Value = 0, .Dock = DockStyle.Right}
Private Buttons As New List(Of Button)()
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
FlowLayoutPanel1.SuspendLayout()
For i = 0 To _max
Dim btn As New Button() With {.Text = i.ToString()}
btn.Height = 50
AddHandler btn.PreviewKeyDown, AddressOf btn_PreviewKeyDown
AddHandler btn.MouseWheel, AddressOf btn_MouseWheel
Buttons.Add(btn)
FlowLayoutPanel1.Controls.Add(btn)
Next
Controls.Add(FlowLayoutPanel1)
FlowLayoutPanel1.ResumeLayout(False)
Controls.Add(_VScrollBar)
Text = "0"
'最後のボタンを表示しきれない対応
With _VScrollBar
.Maximum = .Maximum + .LargeChange - 1
End With
End Sub
Private Sub _VScrollBar_ValueChanged(sender As Object, e As System.EventArgs) Handles _VScrollBar.ValueChanged
FlowLayoutPanel1.SuspendLayout()
For i = _max To 0 Step -1
Buttons(i).Visible = i >= _VScrollBar.Value
Next
FlowLayoutPanel1.ResumeLayout(True)
Me.Text = _VScrollBar.Value.ToString()
End Sub
Private Sub btn_PreviewKeyDown(sender As Object, e As System.Windows.Forms.PreviewKeyDownEventArgs)
Select Case e.KeyCode
Case Keys.Up
_VScrollBar.Value = If(_VScrollBar.Value - 1 < 0, 0, _VScrollBar.Value - 1)
Case Keys.Down
_VScrollBar.Value = If(_VScrollBar.Value + 1 > _max, _max, _VScrollBar.Value + 1)
End Select
End Sub
Private Sub btn_MouseWheel(sender As Object, e As System.Windows.Forms.MouseEventArgs)
Select Case Math.Sign(e.Delta)
Case 1
_VScrollBar.Value = If(_VScrollBar.Value - 1 < 0, 0, _VScrollBar.Value - 1)
Case -1
_VScrollBar.Value = If(_VScrollBar.Value + 1 > _max, _max, _VScrollBar.Value + 1)
End Select
End Sub
End Class
|