0

I have a list with objects inside which have a DateTime property. Using a DataPicker and a TimePicker, I create a DateTime object, which I then insert into the ObservableCollection<>. However, I would like to insert the elements in the list in chronological order with respect to the DateTime. How can I find the right position to put it in the list?

 public class HumorDiary
 {
    public DateTime Dt { get; set; }
 }

HumorDiary obj= new HumorDiary();
obj.Dt= xx/xx/xxxx;

ObservableCollection<HumorDiary> listDiario = new ObservableCollection<HumorDiary>();
    
listDiario.Insert(Position????, obj);
signalover
  • 167
  • 2
  • 7
  • 1
    just sort the list *after* you insert the new object – Jason Mar 03 '21 at 18:14
  • listDiario.OrderBy(x => x.Dt); It is ok? – signalover Mar 03 '21 at 18:42
  • why don't you try it and see if it works? – Jason Mar 03 '21 at 18:50
  • Comparable objects, such as `DateTime` or `string` (as in the duplicate) have a `CompareTo()` method, and `IList` collections such as `ObservableCollection` are amenable to using a binary search (though unlike `List`, ObservableCollection` does not have the method built-in, it's simple enough to implement yourself). You can do a binary search or insertion sort, both of which are described among the answers to the duplicate. – Peter Duniho Mar 03 '21 at 19:40

2 Answers2

0

(Answer edited after testing the code.)

You can sort the list yourself.

listDario.Add(obj);
listDario = new ObservableCollection<HumorDiary>(listDario.OrderBy(x => x.Dt));

To my surprise, this does not actually fire an additional CollectionChanged event. However, note that this creates a new list, and event handlers attached to the list will probably be unlinked. I would also say it's not terribly efficient. If you don't need the event functionality at all, use SortedList<TKey,TValue> instead.

You could also write an extension method like below, but it assumes the list is already sorted, so you'd have to make sure to use it for every insert.

    public static void InsertByDate(this ObservableCollection<HumorDiary> source, HumorDiary obj)
    {
        int idx = 0;
        while (idx < source.Count() && source[idx].Dt <= obj.Dt) {
            idx += 1;
        }
        source.Insert(idx, obj);
    }
dgasaway
  • 66
  • 6
-1

There are more than one methods for achieving this but the simplest one is using OrderBymethod. Here is an example:

        HumorDiary obj1 = new HumorDiary();
        obj1.Dt = DateTime.Now;
        HumorDiary obj2 = new HumorDiary();
        obj2.Dt = DateTime.Now.AddHours(1);
        HumorDiary obj3 = new HumorDiary();
        obj3.Dt = DateTime.Now.AddHours(5);

        ObservableCollection<HumorDiary> listDiario = new ObservableCollection<HumorDiary>();

        listDiario.Add(obj3);
        listDiario.Add(obj2);
        listDiario.Add(obj1);

        listDiario = new ObservableCollection<HumorDiary>(listDiario.OrderBy(obj => obj.Dt));

Notice that you have to cast iorderedenumerable to ObservableCollection after ordering.

Ali Ihsan Elmas
  • 174
  • 4
  • 15
  • This answer completely misses the point of using `ObservableCollection`, which is that the collection _notifies_ client code when the collection changes. If you're just going to _replace_ the collection with a whole new collection, there's no reason to use an _observable_ collection in the first place. – Peter Duniho Mar 03 '21 at 19:42
  • Oh you are right! Thanks for correcting me! – Ali Ihsan Elmas Mar 04 '21 at 07:05