I have a listbox and a (annual holiday) date picker. The user chooses the date and adds it to the Listbox. I then want to sort the Listbox from earliest to latest date. I tried using sorted Listbox but that did not work as it sorts like they are alphabetic strings. I then used unsorted Listbox and found some code and changed it to sort the box manually but again this is alphabetical. I am using the date as dd/mm/yyyy each date on a new line e.g.
If I have:
01/01/2023
02/12/2022
23/12/2022
24/12/2022
then I want the listbox to show me
02/12/2022
23/12/2022
24/12/2022
01/01/2023
what I get is the following where it sorts from left to right rather than year then month then day
01/01/2023
02/12/2022
23/12/2022
24/12/2022
At present I use the following code to add and then sort but there must be an easy way to sort this.
void Btn_add_holidayClick(object sender, EventArgs e)
{
lstbx_annual_hol.Items.Add(DatePick_Hol_Date.Value.Day.ToString("D2") "/"
DatePick_Hol_Date.Value.Month.ToString("D2") "/"
DatePick_Hol_Date.Value.Year.ToString() "\n");
SortAnnualHoliday();
}
void SortAnnualHoliday()
{
ArrayList arList = new ArrayList();
foreach (object obj in lstbx_annual_hol.Items)
{
arList.Add(obj);
}
arList.Sort();
lstbx_annual_hol.Items.Clear();
foreach(object obj in arList)
{
lstbx_annual_hol.Items.Add(obj);
}
}
Thanks in advance for any advice and solutions even if you think I should do it a completely different way.
CodePudding user response:
You get this result because it tries to sort a list of strings not dates. For your purpose you should convert the strings back to dates, sort them, and convert the sorted list to string again:
void SortAnnualHoliday()
{
List<string> arList =lstbx_annual_hol.Items.Cast<string>()
.Select(x => { DateTime.TryParseExact(x, "dd/MM/yyyy", new CultureInfo("en-US"), DateTimeStyles.None, out var y); return y; })
.OrderBy(x => x)
.Select(x => x.ToString("dd/MM/yyyy"))
.ToList();
lstbx_annual_hol.Items.Clear();
lstbx_annual_hol.Items.AddRange(arList.ToArray());
}
CodePudding user response:
Create a List<DateTime>
so that you can SORT it based on the dates within. You can use a BindingSource
to attach the List to your ListBox, making it update whenever changes are made.
Something like:
public partial class Form2 : Form
{
private List<DateTime> dates = new List<DateTime>();
private BindingSource source = new BindingSource();
public Form2()
{
InitializeComponent();
source.DataSource = dates;
lstbx_annual_hol.FormatString = "d";
lstbx_annual_hol.DataSource = source;
}
private void Btn_add_holidayClick(object sender, EventArgs e)
{
dates.Add(DatePick_Hol_Date.Value);
dates.Sort();
source.ResetBindings(false);
}
}