1

In the following code I'm checking if a certain item exists in an ObservableCollection and if it does, I want to grab its index so I can move that item to the top but I cannot figure it out.

My object:

public class RecentFile
{
    public string FileName { get; set; }
    public string DateAdded { get; set; }
}

Cod for finding index of item:

if (recentFilesObservableCollection.Any(f => f.FileName == "MyFileName")) {

    foreach (RecentFile file in recentFilesObservableCollection) {
        if (file.FileName == "MyFileName") {
            var x = RecentFilesDataGrid[(recentFilesObservableCollection.IndexOf(file)];
        }
    }
}

What would be the best way to get the index number if the item exists?

Ultimately what I need to do is...

  1. Check if item exists
  2. If it does move it to the top of the list
Eliahu Aaron
  • 4,103
  • 5
  • 27
  • 37
fs_tigre
  • 10,650
  • 13
  • 73
  • 146
  • 1
    `var index = 0;` outside of the `foreach`. `index++` at the end of (inside) the `foreach`. Or consider https://stackoverflow.com/questions/2471588/how-to-get-index-using-linq . – mjwills Jun 17 '18 at 11:50
  • 1
    Possible duplicate of [How does ObservableCollection.Move(int,int) work?](https://stackoverflow.com/questions/10471222/how-does-observablecollectiont-moveint-int-work) – mjwills Jun 17 '18 at 11:56
  • 1
    Did you try `var index = 0; foreach (RecentFile file in recentFilesObservableCollection) { if (file.FileName == "MyFileName") { recentFilesObservableCollection.Move(index, 0); break; } index++; } `? Note that `Any` is not needed. – mjwills Jun 17 '18 at 12:11

3 Answers3

4

Check if item exists. If it does get the item to find its index. From there move it.

//Check if item exists
if (recentFilesObservableCollection.Any(f => f.FileName == "MyFileName")) {
    //If it does, get item
    var file = recentFilesObservableCollection.First(f => f.FileName == "MyFileName");
    //grab its index
    var index = recentFilesObservableCollection.IndexOf(file);
    if (index > 0)
        //move it to the top of the list
        recentFilesObservableCollection.Move(index, 0);
}

Another alternative that achieves the same result with less enumerations.

var item = recentFilesObservableCollection
    .Select((file, index) => new { file, index })
    .FirstOrDefault(f => f.file.FileName == "MyFileName"));
if(item != null && item.index > 0) // or if(item?.index > 0)
    recentFilesObservableCollection.Move(item.index, 0);
Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • @ Nkosi - It did the trick thanks. Quick question, is there a way to ignore case when checking if file exists? Right now if I check for `"MyFileName"` and `"myFileName"` exists, it returns false. – fs_tigre Jun 18 '18 at 16:10
  • 1
    @fs_tigre use `string.Equals(f.file.FileName, "MyFileName", StringComparison.InvariantCultureIgnoreCase)` to compare them ignoring case. – Nkosi Jun 18 '18 at 16:12
  • Hmm, I'm a little confused with `f.file.FileName` I'm not sure what `file` is, I get an error saying that it doesn't exist in the current context. – fs_tigre Jun 18 '18 at 16:33
  • 1
    @fs_tigre I though you were referring to the second example. Just replace that with what was used in the first example – Nkosi Jun 18 '18 at 16:35
  • Oh, sorry I'm using the code from your first example. – fs_tigre Jun 18 '18 at 16:36
  • FYI - With the second example I had to delete `&& item.index > 0` from the `IF` statement otherwise I would get a crash when `MyFileName` was matched and it was the first item in the collection. After this little adjustment, everything worked great. Thanks! – fs_tigre Jun 19 '18 at 01:42
0

Try this: Int index=YourCollection.IndexOf(x => x.fileName == “name”); And then use MoveItem which takes current index and destination index.

bginsburg
  • 123
  • 4
0

You can create extension methods similar to List<T>.FindIndex(...) methods:

public static class ObservableCollectionExtensions
{
    public static int FindIndex<T>(this ObservableCollection<T> ts, Predicate<T> match)
    {
        return ts.FindIndex(0, ts.Count, match);
    }

    public static int FindIndex<T>(this ObservableCollection<T> ts, int startIndex, Predicate<T> match)
    {
        return ts.FindIndex(startIndex, ts.Count, match);
    }

    public static int FindIndex<T>(this ObservableCollection<T> ts, int startIndex, int count, Predicate<T> match)
    {
        if (startIndex < 0) startIndex = 0;
        if (count > ts.Count) count = ts.Count;

        for (int i = startIndex; i < count; i++)
        {
            if (match(ts[i])) return i;
        }

        return -1;
    }
}

Usage:

int index = recentFilesObservableCollection.FindIndex(f => f.FileName == "MyFileName");
if (index > 0)
{
    // Move it to the top of the list
    recentFilesObservableCollection.Move(index, 0);
}
Eliahu Aaron
  • 4,103
  • 5
  • 27
  • 37