【发布时间】:2021-05-27 18:25:48
【问题描述】:
我发现了一些关于突出显示单元格或列,甚至所有列标题的主题,但我只需要突出显示单个列标题以向用户指示排序。
相关但没有答案: Programmatically focus/highlight a ListView column header in WinForms VB.NET/C#
【问题讨论】:
我发现了一些关于突出显示单元格或列,甚至所有列标题的主题,但我只需要突出显示单个列标题以向用户指示排序。
相关但没有答案: Programmatically focus/highlight a ListView column header in WinForms VB.NET/C#
【问题讨论】:
您可以设置ListView.OwenerDraw = true,然后像这样处理DrawItem、DrawSubItem和DrawHeader:
private void listView1_DrawColumnHeader(object sender,
DrawListViewColumnHeaderEventArgs e)
{
VisualStyleRenderer renderer;
if (e.Bounds.Contains(this.PointToClient(Cursor.Position)))
if (MouseButtons == MouseButtons.Left)
renderer = new VisualStyleRenderer(VisualStyleElement.Header.Item.Pressed);
else
renderer = new VisualStyleRenderer(VisualStyleElement.Header.Item.Hot);
else if (e.ColumnIndex == 1) /* YOUR CRITERIA FOR SELECTED COLUMN*/
renderer = new VisualStyleRenderer(VisualStyleElement.Header.Item.Pressed);
else
renderer = new VisualStyleRenderer(VisualStyleElement.Header.Item.Normal);
renderer.DrawBackground(e.Graphics, e.Bounds);
var d = 3;
var r = new Rectangle(e.Bounds.X + d, e.Bounds.Y + d,
e.Bounds.Width - d, e.Bounds.Height - d);
if (e.Header.ImageList != null && e.Header.ImageIndex > -1)
{
e.Header.ImageList.Draw(e.Graphics, r.Location, e.Header.ImageIndex);
r.X += e.Header.ImageList.ImageSize.Width + d - 2;
r.Width -= (e.Header.ImageList.ImageSize.Width + d - 2);
}
TextRenderer.DrawText(e.Graphics, e.Header.Text, e.Font,
r, e.ForeColor, TextFormatFlags.Left);
}
private void listView1_OnDrawItem(object sender, DrawListViewItemEventArgs e)
{
e.DrawDefault = true;
}
private void OnDrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
e.DrawDefault = true;
}
要支持列的热跟踪,请使用以下派生的ListView:
public class MyListView : ListView
{
public MyListView()
{
DoubleBuffered = true;
}
HeaderControl headerControl;
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (headerControl != null)
headerControl.ReleaseHandle();
headerControl = new HeaderControl(this);
}
private class HeaderControl : NativeWindow
{
const int LVM_GETHEADER = 0x1000 + 31;
const int WM_MOUSEMOVE = 0x0200;
const int WM_LBUTTONDOWN = 0x0201;
const int WM_LBUTTONUP = 0x0202;
const int WM_MOUSELEAVE = 0x02A3;
[DllImport("user32.dll")]
static extern bool InvalidateRect(IntPtr hWnd,
IntPtr lpRect, bool erase);
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd,
int Msg, IntPtr wParam, IntPtr lParam);
ListView listview;
void Invalidate()
{
InvalidateRect(this.Handle, IntPtr.Zero, true);
}
public HeaderControl(ListView listview)
{
this.listview = listview;
var handle = SendMessage(listview.Handle,
LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero);
this.AssignHandle(handle);
listview.HandleDestroyed += (sender, e) => this.ReleaseHandle();
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_MOUSEMOVE ||
m.Msg == WM_LBUTTONDOWN ||
m.Msg == WM_LBUTTONUP ||
m.Msg == WM_MOUSELEAVE)
{
this.Invalidate();
}
base.WndProc(ref m);
}
}
}
【讨论】:
e.DrawText 预计会绘制默认文本渲染。如果由于任何原因不符合您的要求,您可以使用TextRender.DrawText。