DatagridView Tricks

This post will entirely be about the .NET DatagridView control. I will show you how to synchronize the scrolling of two Datagridviews, disable column sorting, disable cell selection and focus cues.

To synchronize the scrolling of two DatagridViews you should subscribe to the Scroll event of the two Datagridviews and add the following code. What it does is equalizing the first row index and the scrolled horizontal offset. I did set the FirstDisplayedScrollingRowIndex because the VerticalScrollingOffset is a readonly property.

private void dataGridViewA_Scroll(object sender, ScrollEventArgs e)
{
    dataGridViewB.FirstDisplayedScrollingRowIndex = dataGridViewA.FirstDisplayedScrollingRowIndex;
    dataGridViewB.HorizontalScrollingOffset = dataGridViewA.HorizontalScrollingOffset;
}

private void dataGridViewB_Scroll(object sender, ScrollEventArgs e)
{
    dataGridViewA.FirstDisplayedScrollingRowIndex = dataGridViewB.FirstDisplayedScrollingRowIndex;
    dataGridViewA.HorizontalScrollingOffset = dataGridViewB.HorizontalScrollingOffset;
}

For the following tricks I created a custom control called DatagridViewGS that derives from the DatagridView control.

Disabling column sorting for all columns is done by setting the SortMode to NotSortable for every column of the DatagridView. In order to do that I subscribed the DataBindingComplete event and added the following code to it

void DatagridViewGS_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
    foreach (DataGridViewColumn c in Columns)
    {
        c.SortMode = DataGridViewColumnSortMode.NotSortable;
    }
}

Cell selection is disabled by subscribing to the CellStateChanged event and setting the Selected property of the cell whose state changed to false. I've also set the SelectionMode of the DataGridView to DataGridViewSelectionMode.CellSelect and the MultiSelect property to false.

void DatagridViewGS_CellStateChanged(object sender, DataGridViewCellStateChangedEventArgs e)
{
    if(e.StateChanged == DataGridViewElementStates.Selected)
        e.Cell.Selected = false;
}

After disabling cell selection there where still focus cues. These are the small dotted lines around the selected elements. To hide these I needed to override ShowFocusCues property of the DataGridView and make it always return false.

protected override bool ShowFocusCues
{
    get
    {
        return false;
    }
}

The full code of my custom DatagridView looked like this :

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace GisSolved.GUI
{
    internal class DatagridViewGS:DataGridView
    {
        public DatagridViewGS()
        {
            MultiSelect = false;
            SelectionMode = DataGridViewSelectionMode.CellSelect;
            CellStateChanged += new DataGridViewCellStateChangedEventHandler(DatagridViewGS_CellStateChanged);
            
            DataBindingComplete += new DataGridViewBindingCompleteEventHandler(DatagridViewGS_DataBindingComplete);
        }
        
        // Disable column sorting
        void DatagridViewGS_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            foreach (DataGridViewColumn c in Columns)
            {
                c.SortMode = DataGridViewColumnSortMode.NotSortable;
            }
        }
        // Disable cell selection
        void DatagridViewGS_CellStateChanged(object sender, DataGridViewCellStateChangedEventArgs e)
        {
            if(e.StateChanged == DataGridViewElementStates.Selected)
                e.Cell.Selected = false;
        }
        // Disable focus cues
        protected override bool ShowFocusCues
        {
            get
            {
                return false;
            }
        }
    }
}

Do you know other useful tricks with DatagridViews or other .NET controls ? Feel free to write them down in the comments section !

Related posts
Drag and drop from ArcCatalog to a .NET form.
Calling .NET code from Python