NewB Q regarding String.Compare

  • Thread starter Visual Systems AB \(Martin Arvidsson\)
  • Start date
V

Visual Systems AB \(Martin Arvidsson\)

Hi!

I am using the IComparer interface to sort items in a ListView, what I am
trying to figure out
is how can the method Compare know how to get the 1st and 2nd value in the
listview, then the 3rd and 4th, and so on?

What is telling the Compare object to do this? Is there a foreach in the
IComparer interface that handles this? How can the IComparer recognize the
list?

Code below

Regards
Martin



private void lvMail_ColumnClick(object sender,
System.Windows.Forms.ColumnClickEventArgs e)
{
this.sortListAscending = !this.sortListAscending;
this.lvMail.ListViewItemSorter = new ListViewItemComparer(e.Column,
sortListAscending);
lvMail.Sort();
}

}

class ListViewItemComparer : IComparer
{
private int col;
private bool _ascending;
public ListViewItemComparer()
{
col=0;
_ascending=true;
}
public ListViewItemComparer( int column, bool ascending )
{
col=column;
_ascending=ascending;
}
public int Compare(object x, object y)
{
if( _ascending )
return String.Compare(((ListViewItem)x).SubItems[col].Text,
((ListViewItem)y).SubItems[col].Text);
else
return String.Compare(((ListViewItem)y).SubItems[col].Text,
((ListViewItem)x).SubItems[col].Text);
}
}
 
M

Mattias Sjögren

What is telling the Compare object to do this? Is there a foreach in the
IComparer interface that handles this? How can the IComparer recognize the
list?

The IComparere interface itself doesn't have any implementation. The
iteration is done (directly or indirectly) by the ListView.Sort()
method.




Mattias
 
G

Guest

I'm not sure that I exactly follow your question but I assume you want to
know how your IComparer method is called for each item. The answer is that,
unlike standard Windows Forms stuff, the ListView is implemented through the
native Common Control library. The ListView class sends a message to the
underlying control and passes it a custom method delegate. The custom
method, implemented inside of ListView, does nothing but call your
IComparer.Compare method on the 2 items given to it in the callback. As a
result the order in which elements are compared is determined by the
underlying common control. It presumably does a simple bubble sort or quick
sort-style algorithm. The net effect however is that when the common control
receives the message to sort it calls back into the custom compare function
of ListView to compare the objects which then calls your IComparer.Compare
method.

Your IComparer is not doing anything special. It simply reacts to the
parameters given to it. If you need access to the various subitems then you
need only access them through casting the parameters. As the IComparer
interface is a standard interface there can't be any custom ListView code in
it. The magic happens in the native code of the common controls. In normal
IComparer circumstances, such as with Array.Sort, the Sort method does the
enumeration itself. Each IComparer-user must determine how to enumerate its
children to do the sorting. There is no logic in the interface to do it.

Hope this answers your question,
Michael Taylor, MCP, MCAD - 6/29/05

Visual Systems AB (Martin Arvidsson) said:
Hi!

I am using the IComparer interface to sort items in a ListView, what I am
trying to figure out
is how can the method Compare know how to get the 1st and 2nd value in the
listview, then the 3rd and 4th, and so on?

What is telling the Compare object to do this? Is there a foreach in the
IComparer interface that handles this? How can the IComparer recognize the
list?

Code below

Regards
Martin



private void lvMail_ColumnClick(object sender,
System.Windows.Forms.ColumnClickEventArgs e)
{
this.sortListAscending = !this.sortListAscending;
this.lvMail.ListViewItemSorter = new ListViewItemComparer(e.Column,
sortListAscending);
lvMail.Sort();
}

}

class ListViewItemComparer : IComparer
{
private int col;
private bool _ascending;
public ListViewItemComparer()
{
col=0;
_ascending=true;
}
public ListViewItemComparer( int column, bool ascending )
{
col=column;
_ascending=ascending;
}
public int Compare(object x, object y)
{
if( _ascending )
return String.Compare(((ListViewItem)x).SubItems[col].Text,
((ListViewItem)y).SubItems[col].Text);
else
return String.Compare(((ListViewItem)y).SubItems[col].Text,
((ListViewItem)x).SubItems[col].Text);
}
}
 

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