Mar*_*rek 4 c# user-interface drawing listview winforms
是否可以拥有列表视图的整个列标题部分?(包括列标题右侧的区域)?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);
}
Run Code Online (Sandbox Code Playgroud)
可用Graphics实例的ClipBounds属性指示未绑定区域(从大负数到大正数).但是在最后一列的列标题区域之外没有任何内容.
有人有解决方案吗?
我很惊讶杰弗里·谭在那篇文章中的回答.他的解决方案无法工作,因为代码试图在标题控件客户区之外绘制.所述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);
}
Run Code Online (Sandbox Code Playgroud)
在列绘制事件处理程序中,您将需要以下内容:
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);
}
Run Code Online (Sandbox Code Playgroud)
但问题在于,由于您的绘图位于客户区之外,因此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);
}
}
Run Code Online (Sandbox Code Playgroud)
这给出了: alt text http://i26.tinypic.com/2m7ex.jpg
[阅读这个答案,我认为这是一个太努力的例子:)希望你能在这里找到有用的东西.]
| 归档时间: |
|
| 查看次数: |
4868 次 |
| 最近记录: |