/// ----------------------------------------------------------------------------- /// <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