为ListView添加自动列宽调整和点击列表头自动排序功能

    技术2024-07-18  60

     

    .Net 2.0中,ListView中虽然增加了AutoResizeColumns函数,允许自动对列宽进行调整,但是对于其中的

     

    AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent) 

    AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent)

     

     

    也就是根据内容自动调整大小的效果却差强人意,因此决定自己动手写一个函数对其允许根据列的内容动态调整大小。下面就是动态调整列宽的函数源码:

     

    private void AutoResizeColumnWidth(ListView lv)  

    {  

        int count = lv.Columns.Count;  

        int MaxWidth = 0;  

        Graphics graphics=lv.CreateGraphics();  

        Font font = lv.Font;  

        ListView.ListViewItemCollection items = lv.Items;  

     

        string str;  

        int width;  

     

        lv.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);  

     

        for (int i = 0; i < count; i++)  

        {  

            str = lv.Columns[i].Text;  

            MaxWidth = lv.Columns[i].Width;  

     

            foreach (ListViewItem item in items)  

            {  

                str = item.SubItems[i].Text;  

                width = (int)graphics.MeasureString(str, font).Width;  

                if (width > MaxWidth)  

                {  

                    MaxWidth = width;  

                }  

            }  

            if (i == 0)  

            {  

                lv.Columns[i].Width = lv.SmallImageList.ImageSize.Width + MaxWidth;  

            }  

            lv.Columns[i].Width = MaxWidth;  

        }  

    } 

            private void AutoResizeColumnWidth(ListView lv)

            {

                int count = lv.Columns.Count;

                int MaxWidth = 0;

                Graphics graphics=lv.CreateGraphics();

                Font font = lv.Font;

                ListView.ListViewItemCollection items = lv.Items;

     

                string str;

                int width;

     

                lv.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);

     

                for (int i = 0; i < count; i++)

                {

                    str = lv.Columns[i].Text;

                    MaxWidth = lv.Columns[i].Width;

     

                    foreach (ListViewItem item in items)

                    {

                        str = item.SubItems[i].Text;

                        width = (int)graphics.MeasureString(str, font).Width;

                        if (width > MaxWidth)

                        {

                            MaxWidth = width;

                        }

                    }

                    if (i == 0)

                    {

                        lv.Columns[i].Width = lv.SmallImageList.ImageSize.Width + MaxWidth;

                    }

                    lv.Columns[i].Width = MaxWidth;

                }

            }

     

    这里先使用了函数

     

    lv.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); 

    lv.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);

     

    目的在于先根据列表头调整大小,初始化MaxWidth为列表头的宽度。

     

    这样就完成了列宽的自动调整。

     

    下面介绍一下列的排序功能。

     

    要对列进行排序,首先要简历自己的排序函数,如下:

     

     class MyListViewSort : System.Collections.IComparer  

    {  

        private int col;  

        private bool descK;  

        public MyListViewSort()  

        {  

            col = 0;  

        }  

        public MyListViewSort(int column, object Desc)  

        {  

            descK = (bool)Desc;  

            col = column; //当前列,0,1,2...,参数由ListView控件的ColumnClick事件传递  

        }  

        public int Compare(object x, object y)  

        {  

            int tempInt = String.Compare(((ListViewItem)x).SubItems[col].Text, ((ListViewItem)y).SubItems[col].Text);  

            if (descK) return -tempInt;  

            else return tempInt;  

        }  

    } 

        class MyListViewSort : System.Collections.IComparer

        {

            private int col;

            private bool descK;

            public MyListViewSort()

            {

                col = 0;

            }

            public MyListViewSort(int column, object Desc)

            {

                descK = (bool)Desc;

                col = column; //当前列,0,1,2...,参数由ListView控件的ColumnClick事件传递

            }

            public int Compare(object x, object y)

            {

                int tempInt = String.Compare(((ListViewItem)x).SubItems[col].Text, ((ListViewItem)y).SubItems[col].Text);

                if (descK) return -tempInt;

                else return tempInt;

            }

        }

     

    其中descK用于描述排列顺序是顺序还是逆序。这是个bool值,绑定在该列的Tag中。

     

    下面就是点击列标头时的事件处理:

     

    view plaincopy to clipboardprint?

    private void listView_ColumnClick(object sender, ColumnClickEventArgs e)  

    {  

        ListView lv = (ListView)sender;  

        if (lv.Columns[e.Column].Tag == null)  

            lv.Columns[e.Column].Tag = true;  

        bool tabK = (bool)lv.Columns[e.Column].Tag;  

        if (tabK)  

            lv.Columns[e.Column].Tag = false;  

        else 

            lv.Columns[e.Column].Tag = true;  

        lv.ListViewItemSorter = new MyListViewSort(e.Column, lv.Columns[e.Column].Tag);  

        //指定排序器并传送列索引与升序降序关键字  

        lv.Sort();//对列表进行自定义排序  

    } 

            private void listView_ColumnClick(object sender, ColumnClickEventArgs e)

            {

                ListView lv = (ListView)sender;

                if (lv.Columns[e.Column].Tag == null)

                    lv.Columns[e.Column].Tag = true;

                bool tabK = (bool)lv.Columns[e.Column].Tag;

                if (tabK)

                    lv.Columns[e.Column].Tag = false;

                else

                    lv.Columns[e.Column].Tag = true;

                lv.ListViewItemSorter = new MyListViewSort(e.Column, lv.Columns[e.Column].Tag);

                //指定排序器并传送列索引与升序降序关键字

                lv.Sort();//对列表进行自定义排序

            }

     

    这样,就简单的完成了对ListView中点击列时的排序功能了。

    最新回复(0)