C# WinForm控件美化扩展系列之ListView(2)

  前面的一篇文章C# WinForm控件美化扩展系列之ListView实现了隔行不同颜色和对列表头进行了美化,但遗憾的是对列表的最后的不包含列头的部分没有进行重绘,主要原因是上次没时间处理,因为处理那一部分是比较困难的,需要花不少时间,今天总算有时间补偿上次的遗憾了。

网上对列表控件(ListView)的美化也很少有对不包含列表部分的重绘,C#的就更加少了,但是很多人都在各个论坛问到这个东西,也少有人回答,主要是这个用到API方面的东西比较多,也不是太好处理,今天把这篇文章写出来,也算是弥补一下这方面的资料吧,也是告诉大家,其他语言能实现的C#也都可以实现,只要找对方法就行了,好了,废话不多说了,进入正题。

ListView其实由两部分组成的,它包含了一个Header部分,用SPY++看看就知道了,要实现对列表最后一部分的美化,直接重写ListViewWndProc方法,截取WM_PAINT或者WM_NCPAINT消息都是不能对他进行很好的处理的,我们需要截取这个Header的消息才行,这点是至关重要的。要怎么截取他的消息,其实前面实有一篇文章C# 实现只能输入数字的ComboBox控件已经用到过这种方法了,以后写的控件可能会经常看到这种方法。第一步就是得到Header的句柄;第二步,继承NativeWindow,实现一个HeaderNativeWindow类,把Header的句柄分配给他。第三步,在HeaderNativeWindow类中重写NativeWindowWndProc方法,然后进行相应的消息处理。在这里,我对WM_PAINT0xF)进行了处理,在这个消息中进行了重绘。但是,我测试的时候发现,当改变ListView的大小的时候,变大没问题,还是正常的绘制,但是变小的时候,Header没有收到WM_PAINT消息,所以就没有重绘,但是可以收到WM_WINDOWPOSCHANGED0x47)消息,所以我就在收到WM_WINDOWPOSCHANGED消息的时候也进行了重绘。第四步,当ListView创建句柄的时候,创建一个HeaderNativeWindow,让它可以截取Header的消息。当ListView销毁句柄时,HeaderNativeWindow也要释放Header的句柄。

方法有了,但是在重绘的时候我们需要知道需要绘制部分的大小和位置,看起来很简单,就是用Header的宽度减去最后一个列表头的最右边所在的位置,就得到要绘制部分的宽度了,高度就是列表头的高度,但是实现起来还是有点麻烦的。先发送一个HDM_GETITEMRECTHeader,获取最右边的列表头的位置和大小,然后再获得Header的大小,这样就可以计算出需要绘制部分的大小和位置了。看看代码:

        private Rectangle HeaderEndRect()

        {

            RECT rect = new RECT();

            IntPtr headerWnd = HeaderWnd;

            SendMessage(

                headerWnd, HDM_GETITEMRECT, ColumnAtIndex(ColumnCount - 1), ref rect);

            int left = rect.Right;

            GetWindowRect(headerWnd, ref rect);

            OffsetRect(ref rect, -rect.Left, -rect.Top);

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值