DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

DataGridをスクロールさせた時に、別のDataGridを同時にスクロールさせる

注意:ここで紹介しているDataGridは、System.Windows.Forms名前空間のDataGrid(Windowsフォーム)です。System.Web.UI.WebControls名前空間のDataGrid(Webフォーム)ではありません。

System.Windows.Forms.DataGridコントロールを垂直方向にスクロールした時に、別のDataGridも同時にスクロールされる方法を紹介します。

まずDataGridコントロールが垂直方向にスクロールされたことを知るには、Scrollイベントを捕捉したり、プロテクトメンバのGridVScrolledメソッドをオーバーライドしたり、同じくプロテクトメンバのVertScrollBarプロパティのScrollイベントを捕捉したりする方法があります。

GridVScrolledメソッドやVertScrollBarプロパティのScrollイベントを捕捉する場合は、注意が必要です。これらは、マウスのホイールを使ったスクロールや、カーソルキーによるスクロールには反応しません。よって、これらによるスクロールにも対応するためには、MouseWheelイベントなどの別の方法も併用する必要があります。

また、DataGridを指定した行までスクロールさせるには、「DataGrid内の指定された行までスクロールする」で紹介している方法が使えます。

以下に同時スクロールを可能にするDataGridの例を示します。ここではScrollイベントによりDataGridがスクロールされたことを感知しています。GridVScrolledメソッドを使った例に関しては、「.NETプログラミング研究」の第64号をご覧ください。

VB.NET
コードを隠すコードを選択
''' <summary>
''' 同時スクロールを可能にするDataGrid
''' </summary>
Public Class MyDataGrid
    Inherits DataGrid

    Public Sub New()
        MyBase.New()
        AddHandler Me.Scroll, AddressOf MyDataGrid_Scroll
    End Sub

    Private _syncScrollGrid As MyDataGrid = Nothing
    ''' <summary>
    ''' 同時にスクロールさせるDataGrid
    ''' </summary>
    Public Property SyncScrollGrid() As MyDataGrid
        Get
            Return _syncScrollGrid
        End Get
        Set(ByVal Value As MyDataGrid)
            If Not _syncScrollGrid Is Me Then
                _syncScrollGrid = Value
            Else
                Throw New ApplicationException("自分自身に設定できません。")
            End If
        End Set
    End Property

    ''' <summary>
    ''' 指定した位置までスクロールさせる
    ''' </summary>
    ''' <param name="rowNum">この行までスクロールする</param>
    Public Sub SetTopRow(ByVal rowNum As Integer)
        Dim args As New ScrollEventArgs(ScrollEventType.LargeIncrement, rowNum)
        MyBase.GridVScrolled(Me, args)
    End Sub

    Private Sub MyDataGrid_Scroll(ByVal sender As Object, ByVal e As EventArgs)
        If Not (_syncScrollGrid Is Nothing) Then
            '指定位置までスクロール
            _syncScrollGrid.SetTopRow(VertScrollBar.Value)
        End If
        'フォーカスが別のコントロールに移動しないようにする
        Me.Focus()
    End Sub
End Class
C#
コードを隠すコードを選択
/// <summary>
/// 同時スクロールを可能にするDataGrid
/// </summary>
public class MyDataGrid : DataGrid
{
    public MyDataGrid() : base()
    {
        this.Scroll += new EventHandler(MyDataGrid_Scroll);
    }

    private MyDataGrid _syncScrollGrid = null;
    /// <summary>
    /// 同時にスクロールさせるDataGrid
    /// </summary>
    public MyDataGrid SyncScrollGrid
    {
        get
        {
            return _syncScrollGrid;
        }
        set
        {
            if (_syncScrollGrid != this)
            {
                _syncScrollGrid = value;
            }
            else
            {
                throw new ApplicationException("自分自身に設定できません。");
            }
        }
    }

    /// <summary>
    /// 指定した位置までスクロールさせる
    /// </summary>
    /// <param name="rowNum">この行までスクロールする</param>
    public void SetTopRow(int rowNum)
    {
        ScrollEventArgs args = 
            new ScrollEventArgs(ScrollEventType.LargeIncrement, rowNum);
        base.GridVScrolled(this, args);
    }

    private void MyDataGrid_Scroll(object sender, EventArgs e)
    {
        if (_syncScrollGrid != null)
        {
            //指定位置までスクロール
            _syncScrollGrid.SetTopRow(VertScrollBar.Value);
        }
        //フォーカスが別のコントロールに移動しないようにする
        this.Focus();
    }
}

このクラスを使用するには、DataGridコントロールをこのMyDataGridに置き換えます。ユーザーがスクロールするDataGridと、そのスクロールと同時にスクロールさせたいDataGridの両方にMyDataGridを使用します。そして、ユーザーがスクロールするMyDataGridのSyncScrollGridプロパティに、同時にスクロールさせたいMyDataGridを指定します。なお両者のMyDataGridの行数は必ず同じにしてください。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • .NET Tipsをご利用いただく際は、注意事項をお守りください。