- 題名: DataGridViewの横スクロールバーについて
- 日時: 2009/12/15 16:59:06
- ID: 26052
- この記事の返信元:
- (なし)
- この記事への返信:
- [26087] Re[1]: DataGridViewの横スクロールバーについて2009/12/17 23:37:34
- ツリーを表示
お疲れ様です。
DataGridViewのHorizontalScrollOffsetプロパティが使えそうです。
横スクロールバーの矢印ボタンの上にダミーのボタンを置いて、
そのボタンをクリックしたときにHorizontalScrollOffsetの値を加減すればOKでした。
長いコードになってしまいましたが試してみてください。
Public Class Form_DataGridViewScrollTest
Inherits Form
Dim DataGridView1 As New DataGridViewScrollTest
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
With Me.DataGridView1
.Dock = DockStyle.Fill
.RowCount = 10
.ColumnCount = 5
' ↓矢印ボタン押下で横スクロールする量を設定する
.HorizontalScrollAmount = 5
End With
Me.Controls.Add(Me.DataGridView1)
MyBase.OnLoad(e)
End Sub
End Class
''' <summary>
''' 横スクロール量設定機能付きDataGridView
''' </summary>
Public Class DataGridViewScrollTest
Inherits DataGridView
Dim WithEvents ArrowLeft As New ControlEx(ScrollButton.Left)
Dim WithEvents ArrowRight As New ControlEx(ScrollButton.Right)
Public Sub New()
AddHandler Me.HorizontalScrollBar.SizeChanged, AddressOf Me.HorizontalScrollBar_SizeChanged
Me._attachArrowButtonsToHorizontalScrollBar()
End Sub
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing Then
RemoveHandler Me.HorizontalScrollBar.SizeChanged, AddressOf Me.HorizontalScrollBar_SizeChanged
Me.ArrowRight.Dispose()
Me.ArrowLeft.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
Dim _horizontalScrolAmount As Integer = 3
''' <summary>
''' 矢印ボタン押下時の移動量
''' </summary>
Public Property HorizontalScrollAmount() As Integer
Get
Return Me._horizontalScrolAmount
End Get
Set(ByVal value As Integer)
Me._horizontalScrolAmount = Math.Max(value, 0)
End Set
End Property
''' <summary>
''' 矢印ボタンを横スクロールバーに配置します
''' </summary>
Private Sub _attachArrowButtonsToHorizontalScrollBar()
Me._setArrowButtonBoundsCore()
Me.HorizontalScrollBar.Controls.Add(Me.ArrowLeft)
Me.HorizontalScrollBar.Controls.Add(Me.ArrowRight)
End Sub
''' <summary>
''' 横スクロールバーのサイズ変更にあわせてボタンを移動
''' </summary>
Private Sub HorizontalScrollBar_SizeChanged(ByVal sender As Object, ByVal e As EventArgs)
Me._setArrowButtonBoundsCore()
End Sub
Private Sub _setArrowButtonBoundsCore()
Dim arrowsize As New Size(SystemInformation.HorizontalScrollBarArrowWidth, _
SystemInformation.HorizontalScrollBarHeight)
Me.ArrowLeft.Location = New Point(0, 0)
Me.ArrowLeft.Size = arrowsize
Me.ArrowRight.Location = New Point(Me.HorizontalScrollBar.ClientSize.Width - arrowsize.Width, 0)
Me.ArrowRight.Size = arrowsize
End Sub
''' <summary>
''' 矢印ボタンClickで横スクロールします
''' </summary>
Private Sub Arrow_ScrollNeeded(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles ArrowLeft.ScrollNeeded, ArrowRight.ScrollNeeded
Select Case DirectCast(sender, ControlEx)._direction
Case ScrollButton.Left
Dim newvalue As Integer = Me.HorizontalScrollingOffset - Me.HorizontalScrollAmount
Me.HorizontalScrollingOffset = Math.Max(newvalue, 0) ' 負の値は不可
Case ScrollButton.Right
Me.HorizontalScrollingOffset += Me.HorizontalScrollAmount
End Select
End Sub
''' <summary>
''' ScrollBarの矢印ボタンの上に配置する矢印ボタン
''' </summary>
Private Class ControlEx
Inherits Control
Public Event ScrollNeeded As EventHandler
Protected Overridable Sub OnScrollNeeded(ByVal e As EventArgs)
RaiseEvent ScrollNeeded(Me, e)
End Sub
Public ReadOnly _direction As ScrollButton
Dim _buttonState As VisualStyles.ScrollBarArrowButtonState
' 矢印ボタン連続押下時のリピート動作を再現するためのTimer
Dim WithEvents Timer1 As New Timer
Public Sub New(ByVal direction As ScrollButton)
Me._direction = direction
Me._setButtonStateNormalCore()
End Sub
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing Then
Me.Timer1.Stop()
Me.Timer1.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
ScrollBarRenderer.DrawArrowButton(e.Graphics, Me.ClientRectangle, Me._buttonState)
MyBase.OnPaint(e)
End Sub
Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
Me._setButtonStatePressedCore()
Me.OnScrollNeeded(EventArgs.Empty)
Me.Timer1.Interval = 400 ' 矢印ボタン連続押下時のリピート開始待ち(ms)
Me.Timer1.Start()
MyBase.OnMouseDown(e)
End Sub
Protected Overrides Sub OnMouseUp(ByVal e As System.Windows.Forms.MouseEventArgs)
Me._setButtonStateNormalCore()
Me.Timer1.Stop()
MyBase.OnMouseUp(e)
End Sub
Private Sub _setButtonStateNormalCore()
Select Case Me._direction
Case ScrollButton.Left
Me._buttonState = VisualStyles.ScrollBarArrowButtonState.LeftNormal
Case ScrollButton.Right
Me._buttonState = VisualStyles.ScrollBarArrowButtonState.RightNormal
End Select
Me.Invalidate()
End Sub
Private Sub _setButtonStatePressedCore()
Select Case Me._direction
Case ScrollButton.Left
Me._buttonState = VisualStyles.ScrollBarArrowButtonState.LeftPressed
Case ScrollButton.Right
Me._buttonState = VisualStyles.ScrollBarArrowButtonState.RightPressed
End Select
Me.Invalidate()
End Sub
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Me.Timer1.Interval = 50 ' 矢印ボタン連続押下時のリピート間隔(ms)
Me.OnScrollNeeded(EventArgs.Empty)
End Sub
End Class
End Class
お疲れ様です。
解決済みのところお邪魔しますが、以下の2点を修正しましたので、
矢印ボタンクラスのコード修正版を掲載します。
(修正箇所)
・矢印ボタン内にマウスカーソルを移動した場合の動作
・矢印ボタン押下のままマウスカーソルを矢印ボタンの外に移動した場合の動作
''' <summary>
''' ScrollBarの矢印ボタンの上に配置する矢印ボタン
''' </summary>
Private Class ControlEx
Inherits Control
Public Event ScrollNeeded As EventHandler
Protected Overridable Sub OnScrollNeeded(ByVal e As EventArgs)
RaiseEvent ScrollNeeded(Me, e)
End Sub
Public ReadOnly _direction As ScrollButton
Dim _buttonState As VisualStyles.ScrollBarArrowButtonState
' 矢印ボタン連続押下時のリピート動作を再現するためのTimer
Dim WithEvents Timer1 As New Timer
Public Sub New(ByVal direction As ScrollButton)
Me._direction = direction
Me._setButtonStateNormalCore()
End Sub
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
Try
If disposing Then
Me.Timer1.Stop()
Me.Timer1.Dispose()
End If
Finally
MyBase.Dispose(disposing)
End Try
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
ScrollBarRenderer.DrawArrowButton(e.Graphics, Me.ClientRectangle, Me._buttonState)
MyBase.OnPaint(e)
End Sub
Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
Me._setButtonStatePressedCore()
Me.OnScrollNeeded(EventArgs.Empty)
Me.Timer1.Interval = 400 ' 矢印ボタン連続押下時のリピート開始待ち(ms)
Me.Timer1.Start()
MyBase.OnMouseDown(e)
End Sub
Protected Overrides Sub OnMouseEnter(ByVal e As System.EventArgs)
Me._setButtonStateHotCore()
MyBase.OnMouseEnter(e)
End Sub
Protected Overrides Sub OnMouseLeave(ByVal e As System.EventArgs)
Me._setButtonStateNormalCore()
MyBase.OnMouseLeave(e)
End Sub
Protected Overrides Sub OnMouseUp(ByVal e As System.Windows.Forms.MouseEventArgs)
Me._stopScrollCore()
MyBase.OnMouseUp(e)
End Sub
Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
If Me.Timer1.Enabled AndAlso Me.ClientRectangle.Contains(e.X, e.Y) = False Then
Me._stopScrollCore()
End If
MyBase.OnMouseMove(e)
End Sub
Private Sub _stopScrollCore()
Me.Timer1.Stop()
Me._setButtonStateNormalCore()
End Sub
Private Sub _setButtonStateHotCore()
Select Case Me._direction
Case ScrollButton.Left
Me._buttonState = VisualStyles.ScrollBarArrowButtonState.LeftHot
Case ScrollButton.Right
Me._buttonState = VisualStyles.ScrollBarArrowButtonState.RightHot
End Select
Me.Invalidate()
End Sub
Private Sub _setButtonStateNormalCore()
Select Case Me._direction
Case ScrollButton.Left
Me._buttonState = VisualStyles.ScrollBarArrowButtonState.LeftNormal
Case ScrollButton.Right
Me._buttonState = VisualStyles.ScrollBarArrowButtonState.RightNormal
End Select
Me.Invalidate()
End Sub
Private Sub _setButtonStatePressedCore()
Select Case Me._direction
Case ScrollButton.Left
Me._buttonState = VisualStyles.ScrollBarArrowButtonState.LeftPressed
Case ScrollButton.Right
Me._buttonState = VisualStyles.ScrollBarArrowButtonState.RightPressed
End Select
Me.Invalidate()
End Sub
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Me.Timer1.Interval = 50 ' 矢印ボタン連続押下時のリピート間隔(ms)
Me.OnScrollNeeded(EventArgs.Empty)
End Sub
End Class
分類:[.NET]
いつもお世話になっています。
環境は:WindowsXP VS.NET2005
DataGridViewの横スクロールバーの移動量を設定できるでしょうか?
お願いします。