Recently, I had to sort items in my listview. Ok, I heard you, “nothing difficult doing that”. But I also had to group them as Outlook does. I mean “according to the date, today items, yesterday items, tomorrow items, next month items,…”
First of all we have to define the label for each group:
private void Form1_Load(object sender, EventArgs e) { string[] groupName = {"Older", "Last month", "4 weeks ago", "3 weeks ago", "2 weeks ago", "Last week", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "Yesterday", "Today", "Tomorrow", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "Next week", "In 2 weeks", "In 3 weeks", "In 4 weeks", "Next month", "Newer"}; // populate the group list foreach(string group in groupName) listView1.Groups.Add(new ListViewGroup(group)); }
Then we have to define what group an item belongs to according to the current date and the item’s date.
internal static int GetDateTimeGroupIndex(DateTime dtRef, DateTime dtSource) { // Because week starts on Monday in France int dtWeekDay = (Convert.ToInt32(dtSource.DayOfWeek) + 6) % 7; int dtRefWeekDay = (Convert.ToInt32(dtRef.DayOfWeek) + 6) % 7; int ts = (dtRef.Date - dtSource.Date).Days; if (ts == 0) return 0; // same day if (ts == 1) return -1; // day before if (ts == -1) return 1; // day after // same week if ((ts > 1) && (ts <= dtRefWeekDay)) return dtWeekDay - 8; if ((-ts > 1) &amp;&amp; (-ts <= 6 - dtRefWeekDay)) return dtWeekDay + 2; // previous / next weeks for (int nIdx = 0; nIdx <= 3; nIdx++) { if ((ts > dtRefWeekDay + nIdx * 7) && (ts <= dtRefWeekDay + (nIdx + 1) * 7)) if (dtRef.Month == dtSource.Month) return -(9 + nIdx); else return -13; if ((-ts > 6 - dtRefWeekDay + nIdx * 7) && (-ts <= 6 - dtRefWeekDay + (nIdx + 1) * 7)) if (dtRef.Month == dtSource.Month) return (9 + nIdx); else return 13; } if (Math.Abs(dtSource.Month - dtRef.Month) == 1) return Math.Sign(ts) * (-13); return Math.Sign(ts) * (-14); }
Finally we have to set for every item the Group property as follow:
DateTime dtDate = DateTime.Now.AddMonths(-2); while(dtDate < DateTime.Now.AddMonths(2)) { ListViewItem item = new ListViewItem("Item " + dtDate.Date.ToString("dd/MM/yyyy")); item.Group = listView1.Groups[GetDateTimeGroupIndex(DateTime.Now, dtDate) + 14]; listView1.Items.Add(item); dtDate = dtDate.AddDays(1); }
PS: as I am French, weeks start on monday, sorry 😉