可以排序的ListView (备份一下,找这个排序实现不容易啊)

    /// -----------------------------------------------------------------------------    /// <summary>リストビューラッパー。</summary>    /// <remarks></remarks>    /// -----------------------------------------------------------------------------    public class ListViewWrapper {         /// <summary>アイコンを保存する変数</summary>        protected ImageList imageList;         /// <summary>ラップ対象のリストビューコントロール。</summary>        protected ListView listView;        /// --------------------------------------------------------------------------------        /// <summary>ラップ対象リストビューへの参照プロパティ。</summary>        /// <value>ListView</value>        /// <remarks>ラップした対象コントロールへの参照を公開するプロパティです。</remarks>        /// --------------------------------------------------------------------------------        public ListView ListView {            get { return listView; }        }         /// <summary>オブジェクトリストビュー要素を保持するコレクション。</summary>        protected Dictionary<int, IObjectListView> dic = new Dictionary<int, IObjectListView>();         /// -----------------------------------------------------------------------------        /// <summary>カラムヘッダの設定。</summary>        /// <param name="headersDic">カラムヘッダディクショナリ。</param>        /// -----------------------------------------------------------------------------        public void SetColumnHeaders(SortedDictionary<int, ColumnHeader> headersDic) {            ColumnHeader[] array = new ColumnHeader[headersDic.Count];            int index = 0;            foreach (ColumnHeader header in headersDic.Values) {                array[index] = header;                index++;            }            this.listView.Columns.AddRange(array);        }         /// --------------------------------------------------------------------------------        /// <summary>        /// IObjectListView インターフェースを実装したオブジェクトリストビュー要素を        /// リストビューに設定します。        /// </summary>        /// <param name="list">IObjectListView</param>        /// <remarks>        /// リストビューの表示値と同時に、内部定義ディクショナリにリストビューのインデックス        /// 値をキーとして、オブジェクトリストビュー要素を設定します。        /// </remarks>        /// --------------------------------------------------------------------------------        public void SetObjectList(List<IObjectListView> list) {            this.dic.Clear();            this.listView.Items.Clear();            ListViewItem[] items = new ListViewItem[list.Count];            int i = 0;            foreach(IObjectListView record in list){                string[] buff = new string[record.Datas.Count];                int j = 0;                foreach (string value in record.Datas.Values) {                    buff[j] = value;                    j++;                }                this.dic.Add(i, record);                items[i] = new ListViewItem(buff);                items[i].Tag = i;                i++;            }            this.listView.Items.AddRange(items);        }         /// --------------------------------------------------------------------------------        /// <summary>リストビュー及び内部オブジェクトリストの内容をクリアします。</summary>        /// <remarks>        /// 内部オブジェクトリストの内容と、ラップしているリストビューの Items(行レコード)        /// をクリアします。        /// </remarks>        /// --------------------------------------------------------------------------------        public void ClearObjectList() {            this.dic.Clear();            this.listView.Items.Clear();        }         /// --------------------------------------------------------------------------------        /// <summary>        /// 現在選択されている項目に対応したオブジェクトリストビュー要素を戻します。        /// </summary>        /// <returns>IObjectListView</returns>        /// <remarks></remarks>        /// --------------------------------------------------------------------------------        public IObjectListView GetSelectedObject() {            if (this.listView.Items.Count <= 0) {                return null;            }            int index;            try {                index = this.listView.SelectedIndices[0];            } catch {                index = 0;            }            return dic[(int)this.listView.Items[index].Tag];        }         /// --------------------------------------------------------------------------------        /// <summary>        /// 現在選択されている項目リストに対応したオブジェクトリストビュー要素リストを戻します。        /// </summary>        /// <returns>IObjectListViewのリスト</returns>        /// <remarks></remarks>        /// --------------------------------------------------------------------------------        public List<IObjectListView> GetSelectedObjectList()        {            List<IObjectListView> retList = new List<IObjectListView>();            if (this.listView.Items.Count <= 0)            {                return null;            }            foreach (int index in this.listView.SelectedIndices)            {                retList.Add(dic[(int)this.listView.Items[index].Tag]);            }            return retList;        }         /// -----------------------------------------------------------------------------        /// <summary>コンストラクタ。</summary>        /// <param name="listView">ラップ対象のリストビューコントロール。</param>        /// <remarks>        /// ラップ時に各種プロパティの設定を行います。複数行選択不可、選択時に全カラム選択、        /// グリッド線を表示、自動ソート無し、詳細表示スタイルの採用、がデフォルトです。        /// この設定を変更した場合、(現状では)本ラッパーは意図通り動作しません。        /// </remarks>        /// -----------------------------------------------------------------------------        public ListViewWrapper(ListView listView) {            this.listView = listView;            this.listView.MultiSelect = false;            this.listView.FullRowSelect = true;            this.listView.GridLines = true;            this.listView.Sorting = SortOrder.None;            this.listView.View = View.Details;             this.listView.ColumnClick += new ColumnClickEventHandler(this.Column_Click);            this.imageList = new ImageList();            this.imageList.Images.Add(SystemEXE.EternalBreeze.Common.Properties.Resources.Sort_Asc);            this.imageList.Images.Add(SystemEXE.EternalBreeze.Common.Properties.Resources.Sort_Desc);        }         /// <summary>        /// ソートするメソッド        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void Column_Click(object sender, ColumnClickEventArgs e)        {            ListView lv = (ListView)sender;                        // 該当カラムに格納する値のタイプが文字列であるかのチェック            bool isStringType = false;            foreach (ListViewItem items in lv.Items) {                try {                    DecimalUtil.Parse(items.SubItems[e.Column].Text.Replace(",", ""));                } catch {                    isStringType = true;                    break;                }            }             // ソートする            if (lv.Sorting == SortOrder.Ascending)            {                lv.Sorting = SortOrder.Descending;                lv.ListViewItemSorter = new ListViewItemComparerDesc(e.Column, isStringType);                IconSetting.SetHeaderSortIcon(lv, e.Column, this.imageList, 1);                IconSetting.GetColumnOrder(lv, e.Column);            }            else            {                lv.Sorting = SortOrder.Ascending;                lv.ListViewItemSorter = new ListViewItemComparer(e.Column, isStringType);                IconSetting.SetHeaderSortIcon(lv, e.Column, this.imageList, 0);            }        }         /// <summary>        /// 昇順演算子        /// </summary>        private class ListViewItemComparer : System.Collections.IComparer        {            private int col;            private bool isStringType;            public ListViewItemComparer()            {                this.col = 0;                this.isStringType = true;            }            public ListViewItemComparer(int column, bool isStringType)            {                this.col = column;                this.isStringType = isStringType;            }            public int Compare(object x, object y)            {                if (this.isStringType)                    return String.Compare(((ListViewItem)x).SubItems[col].Text, ((ListViewItem)y).SubItems[col].Text);                else {                    if (string.IsNullOrEmpty(((ListViewItem)x).SubItems[col].Text))                        return -1;                    else if (string.IsNullOrEmpty(((ListViewItem)y).SubItems[col].Text))                        return 1;                    decimal tmp = DecimalUtil.Parse(((ListViewItem)x).SubItems[col].Text) - DecimalUtil.Parse(((ListViewItem)y).SubItems[col].Text);                    if (tmp < 0)                        return -1;                    else if (tmp > 0)                        return 1;                    else                        return 0;                }            }        }         /// <summary>        /// 降順演算子        /// </summary>        private class ListViewItemComparerDesc : System.Collections.IComparer        {            private int col;            private bool isStringType;            public ListViewItemComparerDesc()            {                this.col = 0;                this.isStringType = true;            }            public ListViewItemComparerDesc(int column, bool isStringType)            {                this.col = column;                this.isStringType = isStringType;            }            public int Compare(object x, object y)            {                if (this.isStringType)                    return String.Compare(((ListViewItem)y).SubItems[col].Text, ((ListViewItem)x).SubItems[col].Text);                else                {                    if (string.IsNullOrEmpty(((ListViewItem)x).SubItems[col].Text))                        return 1;                    else if (string.IsNullOrEmpty(((ListViewItem)y).SubItems[col].Text))                        return -1;                    decimal tmp = DecimalUtil.Parse(((ListViewItem)x).SubItems[col].Text) - DecimalUtil.Parse(((ListViewItem)y).SubItems[col].Text);                    if (tmp < 0)                        return 1;                    else if (tmp > 0)                        return -1;                    else                        return 0;                }            }        }         #region   Windows   API   for   setting   up   Listview   column   header   sort   icon;   get   the   order        private class IconSetting        {            private const UInt32 LVM_GETHEADER = 4127;            private const UInt32 HDM_SETIMAGELIST = 4616;            private const UInt32 LVM_SETCOLUMN = 4122;            private const uint LVCF_FMT = 1;            private const uint LVCF_IMAGE = 16;            private const int LVCFMT_IMAGE = 2048;             public const UInt32 LVM_GETCOLUMN = 4121;            public const UInt32 LVCF_ORDER = 0x0020;             //   Define   the   LVCOLUMN   for   use   with   interop             [StructLayout(LayoutKind.Sequential, Pack = 8, CharSet = CharSet.Auto)]            private struct LVCOLUMN            {                public uint mask;                public int fmt;                public int cx;                public IntPtr pszText;                public int cchTextMax;                public int iSubItem;                public int iImage;                public int iOrder;            }             //   Declare   two   overloaded   SendMessage   functions.   The             //   difference   is   in   the   last   parameter.             [DllImport("user32.dll ")]            private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, UInt32 wParam, UInt32 lParam);             [DllImport("User32 ", CharSet = CharSet.Auto)]            private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, UInt32 wParam, ref   LVCOLUMN lParam);             //sortIconImageList   三角アイコン             public static void SetHeaderSortIcon(ListView listView,                    int sortColumnIndex,                    ImageList sortIconImageList,                    int sortIconIndex)            {                try                {                    IntPtr hc;                    int i;                    //   Assign   the   ImageList   to   the   header   control.                     //   The   header   control   includes   all   columns.                     //   Get   a   handle   to   the   header   control.                     hc = SendMessage(listView.Handle, LVM_GETHEADER, (UInt32)0, (UInt32)0);                     //   Add   the   image   list   to   the   header   control.                     SendMessage(hc, HDM_SETIMAGELIST, (UInt32)0, (UInt32)sortIconImageList.Handle);                     //   Set   the   image   for   each   column.                     //                     //   In   the   following   code,   we   use   successive   images   in   the   image   list   to   place   on                     //   successive   columns   in   the   ColumnHeader   by   looping   through   all   columns.                     //                     //     The   LVCOLUMN   is   also   used   to   define   alignment,                     //     so   by   using   it   here,   we   are   resetting   the   alignment   if   it   was   defined                     //     in   the   designer.   If   you   need   to   set   the   alignment,   you   will   need   to   change                     //     the   code   below   to   set   it   here.                     //                     for (i = 0; i < listView.Columns.Count; i++)                    {                        // modify start ソート列だけアイコンを設定                        if (i != sortColumnIndex)                            continue;                        // modify end                         //   Use   the   LVM_SETCOLUMN   message   to   set   the   column 's   image   index.                         LVCOLUMN col;                        //     col.mask:   include   LVCF_FMT   |   LVCF_IMAGE                         col.mask = LVCF_FMT | LVCF_IMAGE;                         //   LVCFMT_IMAGE                         col.fmt = LVCFMT_IMAGE;                         col.fmt |= 0x1000;                         //   The   image   to   use   from   the   image   list.                         if (i == sortColumnIndex)                            col.iImage = sortIconIndex;                        else                            col.iImage = -1; //No   image   when   it   is   -1                         //     Initialize   the   rest   to   zero.                         col.pszText = (IntPtr)0;                        col.cchTextMax = 0;                        col.cx = 0;                        col.iSubItem = 0;                        col.iOrder = 0;                         //   Send   the   LVM_SETCOLUMN   message.                         //   The   column   that   we   are   assigning   the   image   to   is   defined   in   the   third   parameter.                         SendMessage(listView.Handle, LVM_SETCOLUMN, (UInt32)i, ref   col);                    }                 }                catch (Exception ex)                {                    System.Diagnostics.Trace.WriteLine(ex.ToString());                }            }             ///   <summary>             ///   Get   the   order   index   (zero   based)   of   a   listview   column.             ///   </summary>             ///   <param   name= "listView "> </param>             ///   <param   name= "columnIndex "> </param>             ///   <returns> returns   -1   if   failed. </returns>             public static int GetColumnOrder(ListView listView,                    int columnIndex)            {                try                {                    LVCOLUMN col = new LVCOLUMN();                    col.mask = LVCF_ORDER;                    SendMessage(listView.Handle, LVM_GETCOLUMN, (UInt32)columnIndex, ref   col);                    return col.iOrder;                }                catch (Exception ex)                {                    System.Diagnostics.Trace.WriteLine(ex.ToString());                    return -1;                }            }        }        #endregion     }

转载于:https://my.oschina.net/cjkall/blog/195890

猜你喜欢

转载自blog.csdn.net/weixin_34391854/article/details/91756231