C# WinForm ListView表头末尾空白区域颜色修改方案求助
解决WinForm ListView表头末尾空白区域颜色修改问题
这个空白区域不属于任何列的ColumnHeader范围,所以在DrawListViewColumnHeaderEventHandler里仅处理e.Bounds是覆盖不到它的,以下是可行的解决方案:
前提设置
确保你的ListView满足两个条件:
View属性设为Details(只有该视图会显示表头)OwnerDraw属性设为true(开启自定义绘制)
方案一:在DrawColumnHeader事件中处理
在处理完每列表头的绘制后,针对最后一列计算空白区域并填充颜色:
// 窗体构造函数中绑定事件 public Form1() { InitializeComponent(); listView1.OwnerDraw = true; listView1.View = View.Details; listView1.DrawColumnHeader += ListView1_DrawColumnHeader; // 必须处理Item和SubItem的绘制,否则内容显示异常 listView1.DrawItem += (s, e) => e.DrawDefault = true; listView1.DrawSubItem += (s, e) => e.DrawDefault = true; } private void ListView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e) { // 绘制当前列表头的背景与文本 e.Graphics.FillRectangle(Brushes.Black, e.Bounds); var format = new StringFormat { Alignment = StringAlignment.Center }; e.Graphics.DrawString(e.Header.Text, e.Font, Brushes.White, e.Bounds, format); // 仅在处理最后一列时计算空白区域 if (e.ColumnIndex == listView1.Columns.Count - 1) { // 计算所有列的总宽度 int totalColumnWidth = listView1.Columns.Cast<ColumnHeader>().Sum(ch => ch.Width); // 表头高度取当前列的Bounds高度(所有列表头高度一致) int headerHeight = e.Bounds.Height; // 计算空白区域的矩形范围 Rectangle emptyArea = new Rectangle( totalColumnWidth, e.Bounds.Top, listView1.ClientSize.Width - totalColumnWidth, headerHeight ); // 填充空白区域颜色 e.Graphics.FillRectangle(Brushes.Black, emptyArea); } }
方案二:重写ListView控件处理WM_PAINT消息
如果方案一在某些场景下(比如滚动条状态变化)失效,可以通过重写ListView的消息处理逻辑,在绘制完成后补填空白区域:
public class CustomListView : ListView { protected override void WndProc(ref Message m) { base.WndProc(ref m); const int WM_PAINT = 0x000F; // 仅在Details视图且开启自定义绘制时处理 if (m.Msg == WM_PAINT && View == View.Details && OwnerDraw) { using (Graphics g = CreateGraphics()) { int totalColumnWidth = Columns.Cast<ColumnHeader>().Sum(ch => ch.Width); if (totalColumnWidth < ClientSize.Width) { // 获取表头高度,这里用Font高度加固定padding适配大多数情况 int headerHeight = Font.Height + 8; Rectangle emptyRect = new Rectangle( totalColumnWidth, 0, ClientSize.Width - totalColumnWidth, headerHeight ); g.FillRectangle(Brushes.Black, emptyRect); } } } } }
使用时直接在窗体中替换原生ListView为CustomListView,再按常规方式设置OwnerDraw和绑定绘制事件即可。
内容的提问来源于stack exchange,提问作者q3fuba
相关产品推荐
相关产品推荐

