using qdr.app.studiou.orders2printpack.ProductStorage; using System.Collections; using System.Reflection; namespace qdr.app.studiou.orders2printpack.Extensions { public static class ListViewExtensions { public static void BindData(this ListView listView, IEnumerable data, bool enableSorting = true, Action? itemCustomProcessCallback = null) where TClass : class, IIdentifierGetter { if (data == null) throw new ArgumentNullException(nameof(data)); listView.BeginUpdate(); listView.Items.Clear(); // Get properties of the class var properties = typeof(TClass).GetProperties(BindingFlags.Public | BindingFlags.Instance); // Add data to the ListView foreach (var item in data) AddItemInternal(listView, properties, item, itemCustomProcessCallback: itemCustomProcessCallback); // Auto-resize columns listView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); if (enableSorting) { EnableSorting(listView); } listView.EndUpdate(); } public static ListViewItem AddItem(this ListView listView, TClass item, bool selectItem = false) where TClass : class, IIdentifierGetter { if (item == null) throw new ArgumentNullException(nameof(item)); // Get properties of the class var properties = typeof(TClass).GetProperties(BindingFlags.Public | BindingFlags.Instance); var lvItem = AddItemInternal(listView, properties, item); if (selectItem) lvItem.Selected = true; return lvItem; } private static ListViewItem AddItemInternal(ListView listView, PropertyInfo[] properties, TClass item, bool selectItem = false, Action? itemCustomProcessCallback = null) where TClass : class, IIdentifierGetter { var row = new string[listView.Columns.Count]; foreach (var column in listView.Columns) { var header = column as ColumnHeader; if (header == null) continue; var property = properties.FirstOrDefault(p => string.Equals(p.Name, header.Tag?.ToString(), StringComparison.CurrentCultureIgnoreCase)); if (property == null) continue; var value = property.GetValue(item); var ordinal = header.DisplayIndex; row[ordinal] = value?.ToString() ?? ""; } var lvItem = new ListViewItem(row); lvItem.Tag = item.GetIdentifier(); if (itemCustomProcessCallback != null) itemCustomProcessCallback(lvItem, item); listView.Items.Add(lvItem); return lvItem; } public static void SaveSelection(this ListView listView) { listView.Tag = listView.SelectedItems.Cast().Select(x => x.Tag?.ToString()).ToArray(); } public static void RestoreSelection(this ListView listView) { if (listView.Tag == null) return; var identifiers = (string[])listView.Tag; foreach (var identifier in identifiers) { var item = listView.Items.Cast().FirstOrDefault(x => string.Equals(x.Tag?.ToString(), identifier)); if (item != null) item.Selected = true; } listView.Tag = null; } private static void EnableSorting(ListView listView) { listView.ListViewItemSorter = new ListViewItemComparer(); listView.ColumnClick += (sender, e) => { var sorter = (ListViewItemComparer)listView.ListViewItemSorter; sorter.Column = e.Column; sorter.Order = sorter.Order == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending; listView.Sort(); }; } private class ListViewItemComparer : IComparer { public int Column { get; set; } public SortOrder Order { get; set; } public ListViewItemComparer() { Column = 0; Order = SortOrder.Ascending; } public int Compare(object? x, object? y) { var xobj = x as ListViewItem; var yobj = y as ListViewItem; int compareResult = string.Compare(xobj?.SubItems[Column].Text, yobj?.SubItems[Column].Text); return Order == SortOrder.Ascending ? compareResult : -compareResult; } } } }