none
ListView固定列宽的问题 RRS feed

  • 问题

  • 我这个情况比较特殊,我继承了Listview,使用了

    https://www.codeproject.com/articles/4243/customizing-the-header-control-in-a-listview

    这个继承的控件,因为Columns属性也被修改了所以在调整列宽的时候不能触发ColumnWidthChanged事件。

    我又尝试使用windows消息来解决这个问题

    protected override void WndProc(ref Message m) { case 0x004E://WM_NOTIFY base.WndProc(ref m); Win32.NMHDR nmhdr = (Win32.NMHDR)m.GetLParam(typeof(Win32.NMHDR));

    switch(nmhdr.code)
    {

    case (0-300-26)://HDN_BEGINTRACK .... break; case (0-300-20)://HDN_ITEMCHANGING .... break; case (0-300-27)://HDN_ENDTRACK .... break; }

    但是我的程序是64位的,64位收不到HDN_BEGINTRACK、HDN_ITEMCHANGING、HDN_ENDTRACK这三个消息,不知道什么原因。

    有没有其它办法可以固定列宽?


    • 已编辑 Yooho1 2017年7月4日 23:18 修改代码
    2017年7月4日 23:18

答案

  • 版主你好,是winform的工程,我找到不能正确响应//WM_NOTIFY的原因了,是因为在很多旧的代码中NMHDR结构体定义是这样的

                 [StructLayout(LayoutKind.Sequential)]
    		public struct NMHDR
    		{
    			public IntPtr hwndFrom;
                            public int idFrom;
    			public int code;
    		}

    但是这在64位下不能正确的解析LParam,正确的应该是

      [StructLayout(LayoutKind.Sequential)]
    		public struct NMHDR
    		{
    			public IntPtr hwndFrom;
                            public IntPtr idFrom;
    			public int code;
    		}

    第二个参数应该是一个指针,这样就可以正确的得到nmhdr.code,可以进行下一步的操作了,最后实现的代码:

      protected override void WndProc(ref Message m)
            {
                switch (m.Msg)
                {
                    case 0x004E://WM_NOTIFY
                            Win32.NMHDR nmhdr = (Win32.NMHDR)m.GetLParam(typeof(Win32.NMHDR));
                            switch (nmhdr.code)
                            {
                                case (0 - 300 - 26)://HDN_BEGINTRACK
                                case (0 - 300 - 20)://HDN_ITEMCHANGING
                                case (0 - 300 - 27)://HDN_ENDTRACK
                                    {
                                        m.Result = (IntPtr)1;
                                        return;
                                    }
                            }
                            base.WndProc(ref m);
                        break;
               }
          }

    参考了

    https://www.codeproject.com/Articles/11637/Locking-ListView-Column-Size

    https://social.msdn.microsoft.com/Forums/windows/en-US/a8b182e4-6572-446e-b0d3-6c1c1e32c0fa/why-is-nmhdrcode-always-0-for-virtual-listview-messages-on-win7-x64?forum=winforms

    • 已标记为答案 Yooho1 2017年7月6日 2:13
    2017年7月6日 2:12

全部回复

  • Hi,

    感谢你在MSDN论坛发帖。

    你能告诉我你的工程是Winform的工程, 还是MFC 的工程,还是其他类型?

    在MFC 中使用CListCtrl::SetColumnWidth 方法来改变view 视图的宽度。

    如果是winfrom类型,应该是可以改写这个函数的。ListView.ColumnWidthChanging Event。

    你在编译的时候,有尝试选择32的选项吗?

    你能告诉你在编译的时候,有遇到什么错误吗?

    Best Regards.

    Hart


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年7月5日 3:23
    版主
  • 版主你好,是winform的工程,我找到不能正确响应//WM_NOTIFY的原因了,是因为在很多旧的代码中NMHDR结构体定义是这样的

                 [StructLayout(LayoutKind.Sequential)]
    		public struct NMHDR
    		{
    			public IntPtr hwndFrom;
                            public int idFrom;
    			public int code;
    		}

    但是这在64位下不能正确的解析LParam,正确的应该是

      [StructLayout(LayoutKind.Sequential)]
    		public struct NMHDR
    		{
    			public IntPtr hwndFrom;
                            public IntPtr idFrom;
    			public int code;
    		}

    第二个参数应该是一个指针,这样就可以正确的得到nmhdr.code,可以进行下一步的操作了,最后实现的代码:

      protected override void WndProc(ref Message m)
            {
                switch (m.Msg)
                {
                    case 0x004E://WM_NOTIFY
                            Win32.NMHDR nmhdr = (Win32.NMHDR)m.GetLParam(typeof(Win32.NMHDR));
                            switch (nmhdr.code)
                            {
                                case (0 - 300 - 26)://HDN_BEGINTRACK
                                case (0 - 300 - 20)://HDN_ITEMCHANGING
                                case (0 - 300 - 27)://HDN_ENDTRACK
                                    {
                                        m.Result = (IntPtr)1;
                                        return;
                                    }
                            }
                            base.WndProc(ref m);
                        break;
               }
          }

    参考了

    https://www.codeproject.com/Articles/11637/Locking-ListView-Column-Size

    https://social.msdn.microsoft.com/Forums/windows/en-US/a8b182e4-6572-446e-b0d3-6c1c1e32c0fa/why-is-nmhdrcode-always-0-for-virtual-listview-messages-on-win7-x64?forum=winforms

    • 已标记为答案 Yooho1 2017年7月6日 2:13
    2017年7月6日 2:12
  • 另外你提到的ColumnWidthChanging不好用,详见

    http://blog.csdn.net/magina3/article/details/7381861

    2017年7月6日 2:14