I have a DataGridView and currently it looks like the image below:

What I am trying to acheive is when I hover over any column of any row, the entire row should be highlighted and the background color should turn into a different color, just like in this image below.

Could you please help me with this problem?
You can highlight the row which is under mouse pointer in RowPostPaint event or you can override OnRowPostPaint method in a derived DataGridView. In this method you can paint the whole row yourself or just paint some part of it or draw something over the row:

Example
using System;
using System.Drawing;
using System.Windows.Forms;
public class MyDataGridView : DataGridView
{
public MyDataGridView() { DoubleBuffered = true; }
protected override void OnRowPostPaint(DataGridViewRowPostPaintEventArgs e)
{
base.OnRowPostPaint(e);
if (this.RectangleToScreen(e.RowBounds).Contains(MousePosition))
{
using (var b = new SolidBrush(Color.FromArgb(50, Color.Blue)))
using (var p = new Pen(Color.Blue))
{
var r = e.RowBounds; r.Width -= 1; r.Height -= 1;
e.Graphics.FillRectangle(b, r);
e.Graphics.DrawRectangle(p, r);
}
}
}
protected override void OnMouseMove(MouseEventArgs e){
base.OnMouseMove(e); this.Invalidate();
}
protected override void OnMouseEnter(EventArgs e){
base.OnMouseEnter(e); this.Invalidate();
}
protected override void OnMouseLeave(EventArgs e){
base.OnMouseLeave(e); this.Invalidate();
}
protected override void OnScroll(ScrollEventArgs e){
base.OnScroll(e); this.Invalidate();
}
}
What you see in your second screenshot is not a DataGridView but a ListView in Details mode.
listView1.View = View.Details;
listView1.FulRowSelect = true;
Use Columns to populate columns and Items for rows. The second and further columns in a row can be populated by SubItems property of each items.
By default the row will not be hovered automatically and the selection appearance is an ugly dark blue static line. To show this nice light blue hovering enable the "explorer" theme on your list view by a little trick:
internal sealed class AdvancedListView : ListView
{
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (!DesignMode && Environment.OSVersion.Platform == PlatformID.Win32NT && Environment.OSVersion.Version.Major >= 6)
{
SetWindowTheme(Handle, "explorer", null);
}
}
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
private extern static int SetWindowTheme(IntPtr hWnd, string pszSubAppName, string pszSubIdList);
}
Now you will get exactly the same look and feel as in your second screenshot...
well, except for the ordering. To enable that little arrow, which is also a hidden feature use the class below (note that it sorts by string values in this implementation):
internal class ListViewSorter : IComparer
{
private const int HDI_FORMAT = 0x0004;
private const int HDF_SORTUP = 0x0400;
private const int HDF_SORTDOWN = 0x0200;
private const int LVM_GETHEADER = 0x1000 + 31; // LVM_FIRST + 31
private const int HDM_GETITEM = 0x1200 + 11; // HDM_FIRST + 11
private const int HDM_SETITEM = 0x1200 + 12; // HDM_FIRST + 12
private readonly int column;
private readonly SortOrder sortOrder;
public ListViewSorter(SortOrder sortOrder, int col, ListView listView)
{
IntPtr hColHeader = SendMessage(listView.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero);
HDITEM hdItem = new HDITEM();
IntPtr colHeader = new IntPtr(col);
hdItem.mask = HDI_FORMAT;
SendMessageItem(hColHeader, HDM_GETITEM, colHeader, ref hdItem);
if (sortOrder == SortOrder.Ascending)
{
hdItem.fmt &= ~HDF_SORTDOWN;
hdItem.fmt |= HDF_SORTUP;
}
else if (sortOrder == SortOrder.Descending)
{
hdItem.fmt &= ~HDF_SORTUP;
hdItem.fmt |= HDF_SORTDOWN;
}
else if (sortOrder == SortOrder.None)
{
hdItem.fmt &= ~HDF_SORTDOWN & ~HDF_SORTUP;
}
SendMessageItem(hColHeader, HDM_SETITEM, colHeader, ref hdItem);
this.sortOrder = sortOrder;
this.column = col;
}
protected virtual int DoCompare(ListViewItem item1, ListViewItem item2)
{
return sortOrder == SortOrder.Ascending ? String.Compare(item1.SubItems[column].Text, item2.SubItems[column].Text, CultureInfo.CurrentCulture, CompareOptions.IgnoreCase)
: String.Compare(item2.SubItems[column].Text, item1.SubItems[column].Text, CultureInfo.CurrentCulture, CompareOptions.IgnoreCase);
}
public int Compare(object x, object y)
{
ListViewItem item1 = (ListViewItem)x;
ListViewItem item2 = (ListViewItem)y;
return DoCompare(item1, item2);
}
[StructLayout(LayoutKind.Sequential)]
private struct HDITEM
{
public int mask;
public int cxy;
[MarshalAs(UnmanagedType.LPTStr)] public string pszText;
public IntPtr hbm;
public int cchTextMax;
public int fmt;
public int lParam;
public int iImage;
public int iOrder;
};
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", EntryPoint = "SendMessage")]
private static extern IntPtr SendMessageItem(IntPtr handle, int msg, IntPtr wParam, ref HDITEM lParam);
}
To apply the sorting on the clicked column use the ColumnClick event:
private void advancedListView1_ColumnClick(object sender, ColumnClickEventArgs e)
{
advancedListView1.Sorting = advancedListView1.Sorting == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;
advancedListView1.ListViewItemSorter = new ListViewSorter(advancedListView1.Sorting, e.Column, advancedListView1);
}
In Windows 7 it will look like as in your screenshot. In my Windows 10 it looks like this:

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With