1 | using System;
|
---|
2 | using System.Windows.Forms;
|
---|
3 | using System.Runtime.InteropServices;
|
---|
4 | using System.Collections;
|
---|
5 | using System.Collections.Generic;
|
---|
6 | using System.Linq;
|
---|
7 | using Microsoft.Win32;
|
---|
8 |
|
---|
9 | namespace Common
|
---|
10 | {
|
---|
11 | public enum ColumnDataType { String, Integer, DateTime, Decimal, Custom }
|
---|
12 |
|
---|
13 | public delegate int ListViewItemCompareEventHandler(ListViewItem x, ListViewItem y);
|
---|
14 |
|
---|
15 | public class ListViewColumn
|
---|
16 | {
|
---|
17 | public string Name;
|
---|
18 | public int Width;
|
---|
19 | public HorizontalAlignment TextAlign;
|
---|
20 | public bool Visible;
|
---|
21 | public int FieldIndex;
|
---|
22 | public ColumnDataType DataType;
|
---|
23 | public ListViewItemCompareEventHandler OnCompare;
|
---|
24 | }
|
---|
25 |
|
---|
26 | // Supports sorting by column in ascending or descending order
|
---|
27 | public class ListViewItemComparer : IComparer, IComparer<ListViewItem>
|
---|
28 | {
|
---|
29 | public int Column;
|
---|
30 | public SortOrder Order;
|
---|
31 | public ListView ListView;
|
---|
32 | public ListViewManager ListViewManager;
|
---|
33 |
|
---|
34 | public void ColumnClick(int newColumn)
|
---|
35 | {
|
---|
36 | // Determine if clicked column is already the column that is being sorted.
|
---|
37 | if (newColumn == Column)
|
---|
38 | {
|
---|
39 | // Reverse the current sort direction for this column.
|
---|
40 | Order = Order == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;
|
---|
41 | }
|
---|
42 | else
|
---|
43 | {
|
---|
44 | // Set the column number that is to be sorted; default to ascending.
|
---|
45 | Column = newColumn;
|
---|
46 | Order = SortOrder.Ascending;
|
---|
47 | }
|
---|
48 | }
|
---|
49 |
|
---|
50 | public void SetColumn(int newColumn)
|
---|
51 | {
|
---|
52 | Column = newColumn;
|
---|
53 | }
|
---|
54 |
|
---|
55 | public void SetOrder(SortOrder newOrder)
|
---|
56 | {
|
---|
57 | Order = newOrder;
|
---|
58 | }
|
---|
59 |
|
---|
60 | public ListViewItemComparer()
|
---|
61 | {
|
---|
62 | Column = -1;
|
---|
63 | Order = SortOrder.None;
|
---|
64 | }
|
---|
65 |
|
---|
66 | public int Compare(ListViewItem x, ListViewItem y)
|
---|
67 | {
|
---|
68 | if (Column >= ListView.Columns.Count)
|
---|
69 | {
|
---|
70 | Column = -1;
|
---|
71 | }
|
---|
72 | int result = 0;
|
---|
73 | if (x != null && y != null)
|
---|
74 | {
|
---|
75 | if (Column < x.SubItems.Count && Column < y.SubItems.Count && Column >= 0)
|
---|
76 | {
|
---|
77 | ListViewColumn listViewColumn = null;
|
---|
78 | ColumnDataType dataType = ColumnDataType.String;
|
---|
79 | if (ListView.Columns[Column].Tag != null)
|
---|
80 | {
|
---|
81 | listViewColumn = (ListViewColumn)(ListView.Columns[Column].Tag);
|
---|
82 | dataType = listViewColumn.DataType;
|
---|
83 | }
|
---|
84 |
|
---|
85 | if (dataType == ColumnDataType.Integer)
|
---|
86 | {
|
---|
87 | if (int.TryParse(x.SubItems[Column].Text, out int xi) &&
|
---|
88 | int.TryParse(y.SubItems[Column].Text, out int yi))
|
---|
89 | {
|
---|
90 | if (xi < yi) result = -1;
|
---|
91 | else if (xi > yi) result = 1;
|
---|
92 | else result = 0;
|
---|
93 | }
|
---|
94 | }
|
---|
95 | else if (dataType == ColumnDataType.Decimal)
|
---|
96 | {
|
---|
97 | if (decimal.TryParse(x.SubItems[Column].Text, out decimal xi) &&
|
---|
98 | decimal.TryParse(y.SubItems[Column].Text, out decimal yi))
|
---|
99 | {
|
---|
100 | if (xi < yi) result = -1;
|
---|
101 | else if (xi > yi) result = 1;
|
---|
102 | else result = 0;
|
---|
103 | }
|
---|
104 | }
|
---|
105 | else if (dataType == ColumnDataType.DateTime)
|
---|
106 | {
|
---|
107 | if (DateTime.TryParse(x.SubItems[Column].Text, out DateTime xi) &&
|
---|
108 | DateTime.TryParse(y.SubItems[Column].Text, out DateTime yi))
|
---|
109 | {
|
---|
110 | result = DateTime.Compare(xi, yi);
|
---|
111 | }
|
---|
112 | }
|
---|
113 | else if (dataType == ColumnDataType.Custom)
|
---|
114 | {
|
---|
115 | if (listViewColumn?.OnCompare != null)
|
---|
116 | {
|
---|
117 | result = listViewColumn.OnCompare(x, y);
|
---|
118 | }
|
---|
119 | }
|
---|
120 | else
|
---|
121 | result = string.CompareOrdinal(x.SubItems[Column].Text,
|
---|
122 | y.SubItems[Column].Text);
|
---|
123 | }
|
---|
124 | else
|
---|
125 | {
|
---|
126 | if (ListView.VirtualMode)
|
---|
127 | {
|
---|
128 | bool xSelected = ListView.SelectedIndices.IndexOf(x.Index) != -1;
|
---|
129 | bool ySelected = ListView.SelectedIndices.IndexOf(y.Index) != -1;
|
---|
130 | if (!xSelected && ySelected) result = 1;
|
---|
131 | else if (xSelected && !ySelected) result = -1;
|
---|
132 | }
|
---|
133 | else
|
---|
134 | {
|
---|
135 | if (!x.Selected && y.Selected) result = 1;
|
---|
136 | else if (x.Selected && !y.Selected) result = -1;
|
---|
137 | }
|
---|
138 | }
|
---|
139 | }
|
---|
140 |
|
---|
141 | switch (Order)
|
---|
142 | {
|
---|
143 | case SortOrder.Ascending:
|
---|
144 | return result;
|
---|
145 | case SortOrder.Descending:
|
---|
146 | return -result;
|
---|
147 | case SortOrder.None:
|
---|
148 | default:
|
---|
149 | return 0;
|
---|
150 | }
|
---|
151 | }
|
---|
152 |
|
---|
153 | public int Compare(object x, object y)
|
---|
154 | {
|
---|
155 | return Compare((ListViewItem)x, (ListViewItem)y);
|
---|
156 | }
|
---|
157 | }
|
---|
158 |
|
---|
159 | public class ListViewManager
|
---|
160 | {
|
---|
161 | public List<ListViewColumn> ListColumns;
|
---|
162 | public List<ListViewColumn> VisibleListColumns;
|
---|
163 | public ListView ListView;
|
---|
164 | public List<ListViewItem> ListViewCache;
|
---|
165 | public Dictionary<object, ListViewItem> ListViewDict;
|
---|
166 | private readonly List<ListViewItem> listViewCacheMatched;
|
---|
167 | public delegate void LoadItemHandler(ListViewItem listViewItem, int itemIndex);
|
---|
168 | public event LoadItemHandler LoadItem;
|
---|
169 | public delegate void LoadItemObjectHandler(ListViewItem listViewItem, object item);
|
---|
170 | public event LoadItemObjectHandler LoadItemObject;
|
---|
171 | public delegate bool FilterItemHandler(object item, Dictionary<int, string> filter);
|
---|
172 | public event FilterItemHandler FilterItem;
|
---|
173 | public Dictionary<int, string> Filter;
|
---|
174 |
|
---|
175 | public ListViewManager(ListView listView)
|
---|
176 | {
|
---|
177 | ListView = listView;
|
---|
178 | var listViewComparer = new ListViewItemComparer
|
---|
179 | {
|
---|
180 | ListView = listView,
|
---|
181 | ListViewManager = this
|
---|
182 | };
|
---|
183 | listView.ListViewItemSorter = listViewComparer;
|
---|
184 |
|
---|
185 | ListColumns = new List<ListViewColumn>();
|
---|
186 | foreach (ColumnHeader columnHeader in ListView.Columns)
|
---|
187 | {
|
---|
188 | ListViewColumn listViewColumn = new ListViewColumn()
|
---|
189 | {
|
---|
190 | Name = columnHeader.Text,
|
---|
191 | TextAlign = columnHeader.TextAlign,
|
---|
192 | Width = columnHeader.Width,
|
---|
193 | Visible = true,
|
---|
194 | FieldIndex = Convert.ToInt32(columnHeader.Tag)
|
---|
195 | };
|
---|
196 | columnHeader.Tag = listViewColumn;
|
---|
197 | ListColumns.Add(listViewColumn);
|
---|
198 | }
|
---|
199 | VisibleListColumns = new List<ListViewColumn>();
|
---|
200 | if (listView.VirtualMode)
|
---|
201 | {
|
---|
202 | ListViewCache = new List<ListViewItem>();
|
---|
203 |
|
---|
204 | ListView.RetrieveVirtualItem += delegate (object sender, RetrieveVirtualItemEventArgs e)
|
---|
205 | {
|
---|
206 | e.Item = ListViewCache[e.ItemIndex];
|
---|
207 | };
|
---|
208 | }
|
---|
209 | ListViewDict = new Dictionary<object, ListViewItem>();
|
---|
210 | listViewCacheMatched = new List<ListViewItem>();
|
---|
211 | ListView.ColumnClick += delegate (object sender, ColumnClickEventArgs e)
|
---|
212 | {
|
---|
213 | ((ListViewItemComparer)((ListView)sender).ListViewItemSorter).ColumnClick(e.Column);
|
---|
214 | Sort();
|
---|
215 | };
|
---|
216 | Filter = new Dictionary<int, string>();
|
---|
217 |
|
---|
218 | ConfigureListView();
|
---|
219 | }
|
---|
220 |
|
---|
221 | public void Sort()
|
---|
222 | {
|
---|
223 | ListViewItemComparer listViewComparer = (ListViewItemComparer)ListView.ListViewItemSorter;
|
---|
224 |
|
---|
225 | if (((ListViewItemComparer)ListView.ListViewItemSorter).Column != -1 &&
|
---|
226 | ((ListViewItemComparer)ListView.ListViewItemSorter).Order != SortOrder.None)
|
---|
227 | {
|
---|
228 |
|
---|
229 | if (ListView.VirtualMode)
|
---|
230 | {
|
---|
231 | // Store selected items
|
---|
232 | List<object> selectedItems = null;
|
---|
233 | if (ListView.SelectedIndices.Count > 0)
|
---|
234 | {
|
---|
235 | int[] selected = new int[ListView.SelectedIndices.Count];
|
---|
236 | ListView.SelectedIndices.CopyTo(selected, 0);
|
---|
237 | selectedItems = new List<object>(selected.Length);
|
---|
238 | foreach (int index in ListView.SelectedIndices)
|
---|
239 | {
|
---|
240 | selectedItems.Add(ListViewCache[index].Tag);
|
---|
241 | }
|
---|
242 | }
|
---|
243 |
|
---|
244 | ListViewCache.Sort(listViewComparer);
|
---|
245 | ListView.Refresh();
|
---|
246 |
|
---|
247 | // Restore selected items
|
---|
248 | if (selectedItems != null)
|
---|
249 | {
|
---|
250 | ListView.BeginUpdate();
|
---|
251 | try
|
---|
252 | {
|
---|
253 | ListView.SelectedIndices.Clear();
|
---|
254 | foreach (var selectedObject in selectedItems)
|
---|
255 | {
|
---|
256 | ListView.SelectedIndices.Add(ListViewCache.IndexOf(ListViewDict[selectedObject]));
|
---|
257 | }
|
---|
258 | }
|
---|
259 | finally
|
---|
260 | {
|
---|
261 | ListView.EndUpdate();
|
---|
262 | }
|
---|
263 | }
|
---|
264 | }
|
---|
265 | else
|
---|
266 | {
|
---|
267 | ListView.Sort();
|
---|
268 | }
|
---|
269 | }
|
---|
270 |
|
---|
271 | ListView.SetSortIcon(listViewComparer.Column, listViewComparer.Order);
|
---|
272 | }
|
---|
273 |
|
---|
274 | public void ReloadCache(int itemCount)
|
---|
275 | {
|
---|
276 | ListView.BeginUpdate();
|
---|
277 | try
|
---|
278 | {
|
---|
279 | // Sync number of cached items
|
---|
280 | if (listViewCacheMatched.Count > itemCount) listViewCacheMatched.RemoveRange(itemCount, listViewCacheMatched.Count - itemCount);
|
---|
281 | if (listViewCacheMatched.Capacity < itemCount) listViewCacheMatched.Capacity = itemCount;
|
---|
282 | while (listViewCacheMatched.Count < itemCount)
|
---|
283 | {
|
---|
284 | ListViewItem listViewItem = new ListViewItem();
|
---|
285 | listViewCacheMatched.Add(listViewItem);
|
---|
286 | }
|
---|
287 |
|
---|
288 | // Update items content
|
---|
289 | if (LoadItem != null)
|
---|
290 | {
|
---|
291 | for (int i = 0; i < itemCount; i++)
|
---|
292 | {
|
---|
293 | LoadItem?.Invoke(listViewCacheMatched[i], i);
|
---|
294 | }
|
---|
295 | }
|
---|
296 |
|
---|
297 | if (Filter.Count > 0 && FilterItem != null)
|
---|
298 | {
|
---|
299 | ListViewCache = listViewCacheMatched.FindAll(x => (bool)FilterItem?.Invoke((object)x.Tag, Filter)).ToList();
|
---|
300 | }
|
---|
301 | else
|
---|
302 | {
|
---|
303 | ListViewCache = listViewCacheMatched.ToList();
|
---|
304 | }
|
---|
305 | ListView.VirtualListSize = ListViewCache.Count;
|
---|
306 |
|
---|
307 | ListViewDict = ListViewCache.ToDictionary(key => key.Tag, value => value);
|
---|
308 | Sort();
|
---|
309 | }
|
---|
310 | finally
|
---|
311 | {
|
---|
312 | ListView.EndUpdate();
|
---|
313 | }
|
---|
314 | }
|
---|
315 |
|
---|
316 | public void ReloadCacheItem(ListViewItem listViewItem, int itemIndex)
|
---|
317 | {
|
---|
318 | LoadItem?.Invoke(listViewItem, itemIndex);
|
---|
319 | }
|
---|
320 |
|
---|
321 | public void ReloadCacheItemObject(ListViewItem listViewItem, object item)
|
---|
322 | {
|
---|
323 | LoadItemObject?.Invoke(listViewItem, item);
|
---|
324 | }
|
---|
325 |
|
---|
326 | public void UpdateFromListView()
|
---|
327 | {
|
---|
328 | // Store current width
|
---|
329 | for (int i = 0; i < VisibleListColumns.Count; i++)
|
---|
330 | {
|
---|
331 | VisibleListColumns[i].Width = ListView.Columns[i].Width;
|
---|
332 | }
|
---|
333 | }
|
---|
334 |
|
---|
335 | public void UpdateToListView()
|
---|
336 | {
|
---|
337 | ListView.BeginUpdate();
|
---|
338 | try
|
---|
339 | {
|
---|
340 | VisibleListColumns = ListColumns.FindAll(x => x.Visible);
|
---|
341 |
|
---|
342 | while (ListView.Columns.Count < VisibleListColumns.Count)
|
---|
343 | ListView.Columns.Add("");
|
---|
344 | while (ListView.Columns.Count > VisibleListColumns.Count)
|
---|
345 | ListView.Columns.RemoveAt(ListView.Columns.Count - 1);
|
---|
346 | for (int i = 0; i < VisibleListColumns.Count; i++)
|
---|
347 | {
|
---|
348 | ColumnHeader item = ListView.Columns[i];
|
---|
349 | item.Text = VisibleListColumns[i].Name;
|
---|
350 | item.Width = VisibleListColumns[i].Width;
|
---|
351 | item.TextAlign = VisibleListColumns[i].TextAlign;
|
---|
352 | item.Tag = VisibleListColumns[i];
|
---|
353 | Theme.ApplyTheme(item);
|
---|
354 | }
|
---|
355 | }
|
---|
356 | finally
|
---|
357 | {
|
---|
358 | ListView.EndUpdate();
|
---|
359 | }
|
---|
360 | }
|
---|
361 |
|
---|
362 | public void UpdateColumns()
|
---|
363 | {
|
---|
364 | UpdateFromListView();
|
---|
365 | UpdateToListView();
|
---|
366 | }
|
---|
367 |
|
---|
368 | public void ConfigureListView(int column = -1, SortOrder order = SortOrder.None)
|
---|
369 | {
|
---|
370 | ListViewItemComparer listViewComparer = (ListViewItemComparer)ListView.ListViewItemSorter;
|
---|
371 | listViewComparer.SetOrder(order);
|
---|
372 | listViewComparer.SetColumn(column);
|
---|
373 | if ((column != -1) && (order != SortOrder.None))
|
---|
374 | {
|
---|
375 | Sort();
|
---|
376 | }
|
---|
377 | }
|
---|
378 |
|
---|
379 | public void SetColumnDataType(int fieldIndex, ColumnDataType dataType, ListViewItemCompareEventHandler compareHandler = null)
|
---|
380 | {
|
---|
381 | ListViewColumn column = ListColumns.FirstOrDefault(x => x.FieldIndex == fieldIndex);
|
---|
382 | if (column == null) return;
|
---|
383 | column.DataType = dataType;
|
---|
384 | column.OnCompare = compareHandler;
|
---|
385 | }
|
---|
386 |
|
---|
387 | public void SetColumnVisible(int fieldIndex, bool visible)
|
---|
388 | {
|
---|
389 | ListViewColumn column = ListColumns.FirstOrDefault(x => x.FieldIndex == fieldIndex);
|
---|
390 | if (column == null) return;
|
---|
391 | column.Visible = visible;
|
---|
392 | }
|
---|
393 |
|
---|
394 | public void LoadFromRegistry(string regSubKey)
|
---|
395 | {
|
---|
396 | RegistryKey regKey = Application.UserAppDataRegistry.OpenSubKey(regSubKey) ??
|
---|
397 | Application.UserAppDataRegistry.CreateSubKey(regSubKey);
|
---|
398 |
|
---|
399 | ListViewItemComparer listViewComparer = (ListViewItemComparer)ListView.ListViewItemSorter;
|
---|
400 | listViewComparer.Order = (SortOrder)regKey.GetValueInt("SortOrder", (int)listViewComparer.Order);
|
---|
401 | listViewComparer.Column = regKey.GetValueInt("SortColumn", listViewComparer.Column);
|
---|
402 | foreach (ListViewColumn listViewColumn in ListColumns)
|
---|
403 | {
|
---|
404 | listViewColumn.Width = regKey.GetValueInt("Width" + listViewColumn.Name, listViewColumn.Width);
|
---|
405 | listViewColumn.Visible = regKey.GetValueBool("Visible" + listViewColumn.Name, listViewColumn.Visible);
|
---|
406 | }
|
---|
407 | UpdateToListView();
|
---|
408 | }
|
---|
409 |
|
---|
410 | public void SaveToRegistry(string regSubKey)
|
---|
411 | {
|
---|
412 | RegistryKey regKey = Application.UserAppDataRegistry.OpenSubKey(regSubKey, true) ??
|
---|
413 | Application.UserAppDataRegistry.CreateSubKey(regSubKey);
|
---|
414 |
|
---|
415 | ListViewItemComparer listViewComparer = (ListViewItemComparer)ListView.ListViewItemSorter;
|
---|
416 | regKey.SetValueInt("SortOrder", (int)listViewComparer.Order);
|
---|
417 | regKey.SetValueInt("SortColumn", listViewComparer.Column);
|
---|
418 | foreach (ListViewColumn listViewColumn in ListColumns)
|
---|
419 | {
|
---|
420 | regKey.SetValueInt("Width" + listViewColumn.Name, listViewColumn.Width);
|
---|
421 | regKey.SetValueBool("Visible" + listViewColumn.Name, listViewColumn.Visible);
|
---|
422 | }
|
---|
423 | }
|
---|
424 | }
|
---|
425 |
|
---|
426 | internal static class ListViewExtensions
|
---|
427 | {
|
---|
428 | [StructLayout(LayoutKind.Sequential)]
|
---|
429 | public struct LVCOLUMN
|
---|
430 | {
|
---|
431 | public Int32 mask;
|
---|
432 | public Int32 cx;
|
---|
433 | [MarshalAs(UnmanagedType.LPTStr)]
|
---|
434 | public string pszText;
|
---|
435 | public IntPtr hbm;
|
---|
436 | public Int32 cchTextMax;
|
---|
437 | public Int32 fmt;
|
---|
438 | public Int32 iSubItem;
|
---|
439 | public Int32 iImage;
|
---|
440 | public Int32 iOrder;
|
---|
441 | }
|
---|
442 |
|
---|
443 | const Int32 HDI_WIDTH = 0x0001;
|
---|
444 | const Int32 HDI_HEIGHT = HDI_WIDTH;
|
---|
445 | const Int32 HDI_TEXT = 0x0002;
|
---|
446 | const Int32 HDI_FORMAT = 0x0004;
|
---|
447 | const Int32 HDI_LPARAM = 0x0008;
|
---|
448 | const Int32 HDI_BITMAP = 0x0010;
|
---|
449 | const Int32 HDI_IMAGE = 0x0020;
|
---|
450 | const Int32 HDI_DI_SETITEM = 0x0040;
|
---|
451 | const Int32 HDI_ORDER = 0x0080;
|
---|
452 | const Int32 HDI_FILTER = 0x0100;
|
---|
453 |
|
---|
454 | const Int32 HDF_LEFT = 0x0000;
|
---|
455 | const Int32 HDF_RIGHT = 0x0001;
|
---|
456 | const Int32 HDF_CENTER = 0x0002;
|
---|
457 | const Int32 HDF_JUSTIFYMASK = 0x0003;
|
---|
458 | const Int32 HDF_RTLREADING = 0x0004;
|
---|
459 | const Int32 HDF_OWNERDRAW = 0x8000;
|
---|
460 | const Int32 HDF_STRING = 0x4000;
|
---|
461 | const Int32 HDF_BITMAP = 0x2000;
|
---|
462 | const Int32 HDF_BITMAP_ON_RIGHT = 0x1000;
|
---|
463 | const Int32 HDF_IMAGE = 0x0800;
|
---|
464 | const Int32 HDF_SORTUP = 0x0400;
|
---|
465 | const Int32 HDF_SORTDOWN = 0x0200;
|
---|
466 |
|
---|
467 | const Int32 LVM_FIRST = 0x1000; // List messages
|
---|
468 | const Int32 LVM_GETHEADER = LVM_FIRST + 31;
|
---|
469 | const Int32 HDM_FIRST = 0x1200; // Header messages
|
---|
470 | const Int32 HDM_SETIMAGELIST = HDM_FIRST + 8;
|
---|
471 | const Int32 HDM_GETIMAGELIST = HDM_FIRST + 9;
|
---|
472 | const Int32 HDM_GETITEM = HDM_FIRST + 11;
|
---|
473 | const Int32 HDM_SETITEM = HDM_FIRST + 12;
|
---|
474 |
|
---|
475 | [DllImport("user32.dll")]
|
---|
476 | private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
|
---|
477 |
|
---|
478 | [DllImport("user32.dll", EntryPoint = "SendMessage")]
|
---|
479 | private static extern IntPtr SendMessageLVCOLUMN(IntPtr hWnd, Int32 Msg, IntPtr wParam, ref LVCOLUMN lPLVCOLUMN);
|
---|
480 |
|
---|
481 |
|
---|
482 | // This method used to set arrow icon
|
---|
483 | public static void SetSortIcon(this ListView listView, int columnIndex, SortOrder order)
|
---|
484 | {
|
---|
485 | IntPtr columnHeader = SendMessage(listView.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero);
|
---|
486 |
|
---|
487 | for (int columnNumber = 0; columnNumber <= listView.Columns.Count - 1; columnNumber++)
|
---|
488 | {
|
---|
489 | IntPtr columnPtr = new IntPtr(columnNumber);
|
---|
490 | LVCOLUMN lvColumn = new LVCOLUMN {mask = HDI_FORMAT};
|
---|
491 |
|
---|
492 | SendMessageLVCOLUMN(columnHeader, HDM_GETITEM, columnPtr, ref lvColumn);
|
---|
493 |
|
---|
494 | if (order != SortOrder.None && columnNumber == columnIndex)
|
---|
495 | {
|
---|
496 | switch (order)
|
---|
497 | {
|
---|
498 | case SortOrder.Ascending:
|
---|
499 | lvColumn.fmt &= ~HDF_SORTDOWN;
|
---|
500 | lvColumn.fmt |= HDF_SORTUP;
|
---|
501 | break;
|
---|
502 | case SortOrder.Descending:
|
---|
503 | lvColumn.fmt &= ~HDF_SORTUP;
|
---|
504 | lvColumn.fmt |= HDF_SORTDOWN;
|
---|
505 | break;
|
---|
506 | }
|
---|
507 | lvColumn.fmt |= (HDF_LEFT | HDF_BITMAP_ON_RIGHT);
|
---|
508 | }
|
---|
509 | else
|
---|
510 | {
|
---|
511 | lvColumn.fmt &= ~HDF_SORTDOWN & ~HDF_SORTUP & ~HDF_BITMAP_ON_RIGHT;
|
---|
512 | }
|
---|
513 |
|
---|
514 | SendMessageLVCOLUMN(columnHeader, HDM_SETITEM, columnPtr, ref lvColumn);
|
---|
515 | }
|
---|
516 | }
|
---|
517 | }
|
---|
518 | }
|
---|