是否有可能的OwnerDraw ListView的整列标题部分? (包括该区域的列标题的右侧)? ListView控件是详细信息视图。
这里的回答表明,剩余的空间可以用最后一个栏标题可以得出一起: http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework.windowsforms/topic32927.aspx
但它似乎并没有在所有的工作 - 什么也不绘制头区域之外。
所提出的解决方案是基于通过边界外画:
if (e.ColumnIndex == 3) //last column index
{
Rectangle rc = new Rectangle(e.Bounds.Right, //Right instead of Left - offsets the rectangle
e.Bounds.Top,
e.Bounds.Width,
e.Bounds.Height);
e.Graphics.FillRectangle(Brushes.Red, rc);
}
可用图形实例的ClipBounds属性指示未绑定的区域(从大的负数到大正)。 但没有什么是绘制的最后一列的columnHeader区域之外。
没有任何人有一个解决方案?
我被杰弗里谭在该职位的答案感到惊讶。 他的溶液不能工作,因为代码试图标题控制客户区之外绘制。 所述hDC
自定义绘制(因此所有者绘图)是用于控制的客户区中使用,因此不能用在非客户区作画。 到在报头控制最右边的列右侧的区域是在非客户区。 因此,你需要不同的解决方案。
可能的解决方案
- 高科技和部分有效
您可以启用通过客户端区域外绘制GetDC()
WinAPI的电话:
[System.Runtime.InteropServices.DllImport("user32")]
private static extern IntPtr GetDC(IntPtr hwnd);
[System.Runtime.InteropServices.DllImport("user32")]
private static extern IntPtr ReleaseDC(IntPtr hwnd, IntPtr hdc);
public static IntPtr GetHeaderControl(ListView list) {
const int LVM_GETHEADER = 0x1000 + 31;
return SendMessage(list.Handle, LVM_GETHEADER, 0, 0);
}
在您的专栏抽奖事件处理程序,你需要这样的事情:
if (e.ColumnIndex == 3) //last column index
{
ListView lv = e.Header.ListView;
IntPtr headerControl = NativeMethods.GetHeaderControl(lv);
IntPtr hdc = GetDC(headerControl);
Graphics g = Graphics.FromHdc(hdc);
// Do your extra drawing here
Rectangle rc = new Rectangle(e.Bounds.Right, //Right instead of Left - offsets the rectangle
e.Bounds.Top,
e.Bounds.Width,
e.Bounds.Height);
e.Graphics.FillRectangle(Brushes.Red, rc);
g.Dispose();
ReleaseDC(headerControl, hdc);
}
但这样做的问题是,由于您的绘图是客户端区域外,Windows系统不知道什么时候应绘制。 因此,它有时会消失,然后在Windows认为头需要重绘重绘。
- 技术含量低,但丑
一个额外的空列添加到您的控制,所有者绘制但是你想它不看,使它非常广泛,并关闭水平滚动(可选)。
我知道这是可怕的,但你要找的建议:)
- 最有效的,但还不够完善
使用ObjectListView 。 围绕.NET的ListView此包装可以让你覆盖添加到您的列表 - 覆盖可以ListView控件内的任何地方画画,包括头。 [声明:我ObjectListView的作者,但我仍然认为这是最好的解决办法]
public class HeaderOverlay : AbstractOverlay
{
public override void Draw(ObjectListView olv, Graphics g, Rectangle r) {
if (olv.View != System.Windows.Forms.View.Details)
return;
Point sides = NativeMethods.GetColumnSides(olv, olv.Columns.Count-1);
if (sides.X == -1)
return;
RectangleF headerBounds = new RectangleF(sides.Y, 0, r.Right - sides.Y, 20);
g.FillRectangle(Brushes.Red, headerBounds);
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
g.DrawString("In non-client area!", new Font("Tahoma", 9), Brushes.Black, headerBounds, sf);
}
}
这给了这一点:
[读了这个答案,我认为这是过于卖力的例子:)希望你找到的东西在这里帮助。]