Overriding Compare/ListViewItemSorter

G

Guest

Hello Gurus,

I have a listview, and I only want to add unique items. The problem is, my
code is blowing by my "Contains" statement, adding the item, and then hitting
my Compare code in the class that I have set up for my ListViewItemSorter.

Here is my (simplified) code:

// Note: there are accessor properties, constructors, etc
// that I have omitted here for clarity
public class DBSearchInfo : IComparer
{
// Class1 and Class2 each have a unique ID property
private CClass1 ThisClass1;
private CClass2 ThisClass2;

#region IComparer Members
public int Compare(object x, object y)
{
if (x.GetType() == typeof(DBSearchInfo)
{
DBSearchInfo dbiX = x as DBSearchInfo;
DBSearchInfo dbiY = y as DBSearchInfo;
return dbiX.GetHashCode() - dbiY.GetHashCode();
}
else if (x.GetType() == typeof(ListViewItem)
{
DBSearchInfo lviX = x as ListViewItem;
DBSearchInfo lviY = y as ListViewItem;
return Compare(lviX.Tag, lviY.Tag); // Tag is known to be a
DBSearchInfo item
}
else
{
return 0;
}

public override int GetHashCode()
{
string hashValue = ThisClass1.ID.ToString() +
":" + ThisClass2.ID.ToString();
return hashValue.GetHashCode();
}
}
#endregion
}

// In another class....
private void AddStuffToList(CClass1 Class1)
{
lvwSearchResults.ListViewItemSorter = new DBSearchInfo();

// |
// Some other code
// |

while (MyReader.Read())
{
CClass2 Class2=
new CClass2().GetClass2FromReader(MyReader);

DBSearchInfo ThisTag = new DBSearchInfo(Class1,Class2);
ListViewItem lItem = new ListViewItem(Class2.ItemName);

lItem.SubItems.Add(Class2.ShortName);
lItem.SubItems.Add(Class1.GroupName);

lItem.Tag = ThisTag;

// This is where the problem is
if (! lvwSearchResults.Items.Contains(lItem))
lvwSearchResults.Items.Add(lItem);
}
MyReader.Close();
}

When I hit the "Contains" statement above, it always goes to the "Add"
statement, and then I hit a breakpoint in the Compare function. Everything
in the Compare code seems to work correctly, but too late.

Have I implemented the wrong interface for the Contains test?

Thanks,
pagates
 
O

Oliver Sturm

pagates wrote:

// This is where the problem is
if (! lvwSearchResults.Items.Contains(lItem))
lvwSearchResults.Items.Add(lItem);
}
MyReader.Close();
}

When I hit the "Contains" statement above, it always goes to the "Add"
statement, and then I hit a breakpoint in the Compare function. Everything
in the Compare code seems to work correctly, but too late.

Have I implemented the wrong interface for the Contains test?

I don't think there's an interface that needs to, or can, be implemented
to support Contains in this context. I had a quick look into Reflector
and it doesn't look like the list view items collection would ever use
any external implementation to find out whether a given item is already
in the collection. What gave you the idea that it should do this?

You could try to store your own Hashtable (or Set, if you use
PowerCollections) of the item contents that are already in the list.
It's only a reference, so it shouldn't take up too many resources, and
lookup in a Hashtable or other specialized collection class is fast.


Oliver Sturm
 
G

Guest

Oliver Sturm said:
I don't think there's an interface that needs to, or can, be implemented
to support Contains in this context. I had a quick look into Reflector
and it doesn't look like the list view items collection would ever use
any external implementation to find out whether a given item is already
in the collection. What gave you the idea that it should do this?

You could try to store your own Hashtable (or Set, if you use
PowerCollections) of the item contents that are already in the list.
It's only a reference, so it shouldn't take up too many resources, and
lookup in a Hashtable or other specialized collection class is fast.

Oliver Sturm

Hi Oliver,

Thanks for the reply - I've implemented the functionality I've wanted by
using a global ArrayList (for now, unless speed becomes an issue).

I wanted to make sure that the list items were unique. The list is a
collection of search results on two types of related data, and I didn't want
to duplicate entries in the list. I would have thought that the Contains
method would allow me to check for a duplicate item. Another example may be
handling Drag and Drop, preventing duplicate items from being dropped onto
the list.

I am guessing that because I am checking a new ListViewItem, rather than an
existing ListViewItem, that it fails. However, in that case, what is the
purpose of the Contains method? If I need to use an existing ListViewItem, I
know it exists, so it is therefore contained in the collection. Anybody have
an explination or example of "properly" using the Contains method for
ListViewItems?

Thanks Again,
pagates
 
O

Oliver Sturm

pagates said:
I am guessing that because I am checking a new ListViewItem, rather than an
existing ListViewItem, that it fails.

Right, and because the Contains doesn't use the IComparer interface to
check equality of objects.
However, in that case, what is the
purpose of the Contains method? If I need to use an existing ListViewItem, I
know it exists, so it is therefore contained in the collection. Anybody have
an explination or example of "properly" using the Contains method for
ListViewItems?

Well, for one thing the ListViewItems implement the interface IList and
this interface defines the Contains method. So the implementor of that
specific collection type didn't really have a choice of whether or not
to implement the method.

The method in general serves the purpose of finding out whether a given
object is in a collection or not. You could have loads of objects of a
given type and several collections, so there are a number of reasons why
you might want to know if a given object is in a given collection.

You are probably right that it doesn't make as much sense in a simple
scenario with a single list view :)



Oliver Sturm
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top