123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Globalization;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- namespace ListViewNativeArrowIconPoC
- {
- internal static class ListViewExtension
- {
- // ReSharper disable InconsistentNaming
- // ReSharper disable UnusedMember.Local
- private const Int32 HDI_WIDTH = 0x0001;
- private const Int32 HDI_HEIGHT = HDI_WIDTH;
- private const Int32 HDI_TEXT = 0x0002;
- private const Int32 HDI_FORMAT = 0x0004;
- private const Int32 HDI_LPARAM = 0x0008;
- private const Int32 HDI_BITMAP = 0x0010;
- private const Int32 HDI_IMAGE = 0x0020;
- private const Int32 HDI_DI_SETITEM = 0x0040;
- private const Int32 HDI_ORDER = 0x0080;
- private const Int32 HDI_FILTER = 0x0100;
- private const Int32 HDF_LEFT = 0x0000;
- private const Int32 HDF_RIGHT = 0x0001;
- private const Int32 HDF_CENTER = 0x0002;
- private const Int32 HDF_JUSTIFYMASK = 0x0003;
- private const Int32 HDF_RTLREADING = 0x0004;
- private const Int32 HDF_OWNERDRAW = 0x8000;
- private const Int32 HDF_STRING = 0x4000;
- private const Int32 HDF_BITMAP = 0x2000;
- private const Int32 HDF_BITMAP_ON_RIGHT = 0x1000;
- private const Int32 HDF_IMAGE = 0x0800;
- private const Int32 HDF_SORTUP = 0x0400;
- private const Int32 HDF_SORTDOWN = 0x0200;
- private const Int32 LVM_FIRST = 0x1000; // List messages
- private const Int32 LVM_GETHEADER = LVM_FIRST + 31;
- private const Int32 HDM_FIRST = 0x1200; // Header messages
- private const Int32 HDM_SETIMAGELIST = HDM_FIRST + 8;
- private const Int32 HDM_GETIMAGELIST = HDM_FIRST + 9;
- private const Int32 HDM_GETITEM = HDM_FIRST + 11;
- private const Int32 HDM_SETITEM = HDM_FIRST + 12;
- // ReSharper restore UnusedMember.Local
- // ReSharper restore InconsistentNaming
- [DllImport("user32.dll")]
- private static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
- [DllImport("user32.dll", EntryPoint = "SendMessage")]
- private static extern IntPtr SendMessageLVCOLUMN(IntPtr hWnd, Int32 msg, IntPtr wParam, ref LVCOLUMN lPlvcolumn);
- //This method used to set arrow icon
- public static void SetSortIcon(this ListView listView, int columnIndex, SortOrder order)
- {
- var columnHeader = SendMessage(listView.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero);
- for (var columnNumber = 0; columnNumber <= listView.Columns.Count - 1; columnNumber++)
- {
- var columnPtr = new IntPtr(columnNumber);
- var lvColumn = new LVCOLUMN { mask = HDI_FORMAT };
- SendMessageLVCOLUMN(columnHeader, HDM_GETITEM, columnPtr, ref lvColumn);
- if (order != SortOrder.None && columnNumber == columnIndex)
- {
- switch (order)
- {
- case SortOrder.Ascending:
- lvColumn.fmt &= ~HDF_SORTDOWN;
- lvColumn.fmt |= HDF_SORTUP;
- break;
- case SortOrder.Descending:
- lvColumn.fmt &= ~HDF_SORTUP;
- lvColumn.fmt |= HDF_SORTDOWN;
- break;
- }
- lvColumn.fmt |= (HDF_LEFT | HDF_BITMAP_ON_RIGHT);
- }
- else
- {
- lvColumn.fmt &= ~HDF_SORTDOWN & ~HDF_SORTUP & ~HDF_BITMAP_ON_RIGHT;
- }
- SendMessageLVCOLUMN(columnHeader, HDM_SETITEM, columnPtr, ref lvColumn);
- }
- }
- [StructLayout(LayoutKind.Sequential)]
- private struct LVCOLUMN
- {
- public Int32 mask;
- private readonly Int32 cx;
- [MarshalAs(UnmanagedType.LPTStr)]
- private readonly string pszText;
- private readonly IntPtr hbm;
- private readonly Int32 cchTextMax;
- public Int32 fmt;
- private readonly Int32 iSubItem;
- private readonly Int32 iImage;
- private readonly Int32 iOrder;
- }
- }
- public class ColumnSorter : IComparer
- {
- private readonly Comparer _listViewItemComparer;
- private int _sortColumn;
- private SortOrder _sortOrder;
- public ColumnSorter()
- {
- _sortColumn = 0;
- _sortOrder = SortOrder.None;
- _listViewItemComparer = new Comparer(CultureInfo.CurrentUICulture);
- }
- public int SortColumn
- {
- set { _sortColumn = value; }
- get { return _sortColumn; }
- }
- public SortOrder Order
- {
- set { _sortOrder = value; }
- get { return _sortOrder; }
- }
- /// <summary>
- /// This method is inherited from the IComparer interface. It compares the two objects passed using a case insensitive
- /// comparison.
- /// </summary>
- /// <param name="x">First object to be compared</param>
- /// <param name="y">Second object to be compared</param>
- /// <returns>
- /// The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater
- /// than 'y'
- /// </returns>
- public int Compare(object x, object y)
- {
- try
- {
- var lviX = (ListViewItem)x;
- var lviY = (ListViewItem)y;
- int compareResult;
- if (lviX.SubItems[_sortColumn].Tag != null && lviY.SubItems[_sortColumn].Tag != null)
- {
- compareResult = _listViewItemComparer.Compare(lviX.SubItems[_sortColumn].Tag,
- lviY.SubItems[_sortColumn].Tag);
- }
- else
- {
- compareResult = _listViewItemComparer.Compare(lviX.SubItems[_sortColumn].Text,
- lviY.SubItems[_sortColumn].Text);
- }
- if (_sortOrder == SortOrder.Ascending)
- {
- return compareResult;
- }
- if (_sortOrder == SortOrder.Descending)
- {
- return (-compareResult);
- }
- return 0;
- }
- catch
- {
- return 0;
- }
- }
- }
- }
|