答案 0 :(得分:4)
您可以在RowPostPaint
事件中突出显示鼠标指针下的行,也可以在派生的DataGridView
中覆盖OnRowPostPaint
事件。在这种方法中,您可以自己绘制整行,或者只绘制其中的一部分或在行上绘制一些东西:
示例强>
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();
}
}
答案 1 :(得分:2)
您在第二个屏幕截图中看到的内容不是DataGridView
,而是ListView
模式中的Details
。
listView1.View = View.Details;
listView1.FulRowSelect = true;
使用Columns
填充列,Items
填充行。连续的第二列和更多列可以通过每个项目的SubItems
属性填充。
默认情况下,该行不会自动悬停,选择外观是一条丑陋的深蓝色静态线。要显示这个漂亮的淡蓝色悬停,可以通过一个小技巧在列表视图中启用“资源管理器”主题:
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);
}
现在,您将获得与第二个屏幕截图完全相同的外观和感觉......
好吧,除了订购。要启用那个也是隐藏功能的小箭头,请使用下面的类(请注意,它在此实现中按字符串值排序):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);
}
要对点击的列应用排序,请使用ColumnClick
事件:
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);
}
在Windows 7中,它将如截图所示。在我的Windows 10中它看起来像这样:
答案 2 :(得分:0)
你可以这样做:
private void dataGridView1_CellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
{ DataGridView1.ClearSelection();
If (e.RowIndex > -1) { DataGridView1.Rows(e.RowIndex).Selected = True; } }
我认为使用行的背景颜色是不可能的,但我不确定...