Reputation: 1007
I have a list of rows having many columns. Say, a song is a row, and album,artist,title,year are it's columns. These are displayed in a list view. When i multi-select, say 5 songs, i need to check if the artist is the same for all 5 songs or not. The same for album,title,year.
my pseudo-code is as follows:
ListView.SelectedListViewItemCollection selectedItem = this.lvuFiles.SelectedItems;
foreach (ListViewItem itemSelected in selectedItem)
{
// pass a list of 'title's to a method to check for equality
}
i have implemented the method which checks for equality. I just could not figure out how to store the lists (title list,album list, etc) and pass them.
EDIT:
Screenshot of List View http://i.min.us/iexmSg.png
now, i need to check the 3 Titles are matching or not. One way i thought was to add all the titles to a list and pass to the method. Do the same for artist,album. I could not get the selectedItems' value. SO, i have to maintain multiple lists for multiple properties. Is there any better way. As for the suggestions given, i tried the linq one. Says, method not defined.
Upvotes: 1
Views: 2492
Reputation: 128307
Is there any better way.
Absolutely. The LINQ suggestion, for starters, is perfect; the only problem is that the type of the ListView.SelectedItems
property does not implement IEnumerable<ListViewItem>
; I'm guessing that's why it didn't work for you. You can fix this with a simple Cast<T>
call:
if (listView.SelectedItems.Count > 0)
{
var titles = from x in listView.SelectedItems.Cast<ListViewItem>()
select x.SubItems[titleColumn.Index].Text;
string firstTitle = titles.First();
bool allSameTitle = titles.All(t => t == firstTitle);
}
Now, if the real reason the LINQ suggestion didn't work for you is that you're stuck on .NET 2.0, fear not. You can still genericize this behavior. Define a method to look at each item in an IEnumerable
and, based on some selector function, determine whether they all meet a given criterion. Here's an example of how you might do it:
public static bool All(IEnumerable source, Predicate<object> criterion)
{
foreach (object item in source)
{
if (!criterion(item))
{
return false;
}
}
return true;
}
Then you would call this method like this on your ListView.SelectedItems
:
if (listView.SelectedItems.Count > 0)
{
string firstTitle = listView.SelectedItems[0].SubItems[titleColumn.Index].Text;
Predicate<object> sameTitle = delegate(object obj)
{
if (!(obj is ListViewItem))
{
return false;
}
return ((ListViewItem)obj).SubItems[titleColumn.Index].Text == firstTitle;
};
bool allSameTitle = All(listView.SelectedItems, sameTitle);
}
Upvotes: 1
Reputation: 13665
You could use the linq functional set operator 'All'.
using System.Linq;
...
var title = selectedItems.First().Column["Title"].Value;
var sameTitle = selectedItems.All(i => i.Column["Title"].Value == title);
// repeat for artist, album, year, etc.
I don't know the exact syntax of how to get a hold of the values but hopefully you can translate it. I think the key is to just note that what you're essentially asking is "are all values the same". Link is your friend for such set operations.
Upvotes: 0