|
You are very welcome and I'm glad to hear that you liked it. Thanks
A complex system that does not work is invariably found to have evolved from a simpler system that worked just fine. - Murphy's Law of Computing
|
|
|
|
|
I had to change the following line from public to internal when I included your code in a CLS Compliant class library.
[DllImport("kernel32.dll", CharSet=CharSet.Ansi, ExactSpelling=true)]
internal static extern UIntPtr GetProcAddress(IntPtr hModule, string procName);
|
|
|
|
|
Thanks for spotting this. Actually all these imports should have been made private. It will be fixed in the next update.
A complex system that does not work is invariably found to have evolved from a simpler system that worked just fine. - Murphy's Law of Computing
|
|
|
|
|
Hi,
I was using Application.EnableVisualStyles() to enable XP Style theme for my form, but if i create a ListViewSortManager in the constructor and then launch a new form the XP Visual Style is disabled for some weird reason. Do you have any idea as to why?
Regards,
Vedavyas K.P
Your Anger is a Gift
|
|
|
|
|
It's a Visual Studio bug (I only noticed it when using C#)
Just add this line after Application.EnableVisualStyles();
Application.DoEvents();
|
|
|
|
|
Thanks that fixed the problem.
Your Anger is a Gift
|
|
|
|
|
You saved me a ton of research! Awesome!
Todd
|
|
|
|
|
You are welcome!
A complex system that does not work is invariably found to have evolved from a simpler system that worked just fine. - Murphy's Law of Computing
|
|
|
|
|
|
I'm glad you liked it!
A complex system that does not work is invariably found to have evolved from a simpler system that worked just fine. - Murphy's Law of Computing
|
|
|
|
|
Hello,
First of all, great little component. I want to contribute with one sorter I developed (se below). I found a bug. When you disable sorting and reenable it (by setting SortEnabled to true ) if no column has been clicked yet, m_column is -1 and an exception is thrown when the ListViewItemSorter property of the ListView is set (invalid index in the array).
I'm currently trying to fix that bug, I'll update this post with the changes when I'm done.
As promised my ListViewCurrencyComparer :
public class ListViewCurrencySort: ListViewTextSort
{
public ListViewCurrencySort(int sortColumn, bool ascending):
base(sortColumn, ascending)
{
}
protected override int OnCompare(string lhs, string rhs)
{
decimal result =
decimal.Parse(lhs, NumberStyles.Currency) -
decimal.Parse(rhs, NumberStyles.Currency);
if(result > 0)
return 1;
else if(result < 0)
return -1;
else
return 0;
}
}
Thanks for such a great piece of code!
-- LuisR
Luis Alonso Ramos
Intelectix - Chihuahua, Mexico
Not much here: My CP Blog!
|
|
|
|
|
I just fixed it. Just change the SortEnabled property to keep its value in another variable instead of the ListViewItemSorter property of the ListView:
bool _sortEnabled = true;
public Boolean SortEnabled
{
get
{
return _sortEnabled;
}
set
{
if(value)
{
if(!this.SortEnabled)
{
m_list.ColumnClick += new ColumnClickEventHandler(ColumnClick);
if(m_column != -1)
m_list.ListViewItemSorter = (ListViewTextSort) Activator.CreateInstance(m_comparers[m_column], new Object[] { m_column, m_sortOrder == SortOrder.Ascending } );
ShowHeaderIcon(m_list, m_column, m_sortOrder);
}
}
else
{
if(this.SortEnabled)
{
m_list.ColumnClick -= new ColumnClickEventHandler(ColumnClick);
m_list.ListViewItemSorter = null;
ShowHeaderIcon(m_list, m_column, SortOrder.None);
}
}
_sortEnabled = value;
}
} Thanks again for such a great piece of code.
-- LuisR
Luis Alonso Ramos
Intelectix - Chihuahua, Mexico
Not much here: My CP Blog!
|
|
|
|
|
Good catch! I'll include your fix, the currency sorter and an IP address sorter in the next version.
Me alegra mucho que te haya gustado este control. Desafortunadamente no he tenido mucho tiempo de programar en C# desde que comence a trabajar en Amazon.com. Solo Perl y Java...
A complex system that does not work is invariably found to have evolved from a simpler system that worked just fine. - Murphy's Law of Computing
|
|
|
|
|
Eddie Velasquez wrote:
Good catch! I'll include your fix, the currency sorter and an IP address sorter in the next version.
This is what's really cool about CodeProject: someone develops a nice piece of code, shares it, and then other people help make it better! and then, it saves a lot of time for other people.
Eddie Velasquez wrote:
Me alegra mucho que te haya gustado este control. Desafortunadamente no he tenido mucho tiempo de programar en C# desde que comence a trabajar en Amazon.com. Solo Perl y Java...
[Translation for non-Spanish-speakers: I'm glad you liked this control. Unfortunately I haven't had much time to program in C# since I started working at Amazon.com. Only Perl and Java...]
I knew you spoke Spanish (just from reading your name.) Where are you from? Where do you live right now? And how's work at Amazon?
-- LuisR
Luis Alonso Ramos
Intelectix - Chihuahua, Mexico
Not much here: My CP Blog!
|
|
|
|
|
Well, I was born in New York and moved to Colombia when I was 7. I moved back to the US 7 years ago and started working at Amazon in january. I love working at Amazon, it's a great work environment with a lot of very smart people. It been quite a challenge because I've been a Windows developer all my life and now I'm doing Linux, Perl, Java, etc... anything but Windows! Anyway, we are in a hiring spree right now!
A complex system that does not work is invariably found to have evolved from a simpler system that worked just fine. - Murphy's Law of Computing
|
|
|
|
|
Anyone know how I would sort IP addresses?
Thanks.
|
|
|
|
|
I haven't done this but it shouldn't be difficult at all.
Start out whith something like this: (I have not tested this code!)
public class ListViewIPSort: ListViewTextSort
{
public ListViewIPSort(int column, bool ascending):
base(column, ascending)
{
}
protected override int OnCompare(string lhs, string rhs)
{
IPAddress lhsip = IPAddress.Parse(lhs);
IPAddress rhsip = IPAddress.Parse(rhs);
return lhsip.CompareTo(rhsip);
}
}
A complex system that does not work is invariably found to have evolved from a simpler system that worked just fine. - Murphy's Law of Computing
|
|
|
|
|
Thanks for your quick reply Eddie,
Seems like it will work, but it complains:
Object must be of type Int64. This happens during sort.
Any ideas?
Thanks
|
|
|
|
|
Nevermind got it working thanks!
User error!
public class ListViewIPSort: ListViewTextSort
{
public ListViewIPSort(int column, bool ascending):
base(column, ascending)
{
}
protected override int OnCompare(string lhs, string rhs)
{
IPAddress lhsip = IPAddress.Parse(lhs);
IPAddress rhsip = IPAddress.Parse(rhs);
return lhsip.Address.CompareTo(rhsip.Address);
}
}
|
|
|
|
|
Your sorting routine works great but when I try to sort strings that have hyphen - it seems to ignore this character. Example:
Here is my data:
PS-05
PS-10-24
PS2-61P
PS2-61
PS-52
PS6-2
PS5-1
Here is how it sorts:
PS-05
PS-10-24
PS2-61
PS2-61P
PS5-1
PS-52
PS6-2
I would like it to sort like this (by ascii value):
PS-05
PS-10-24
PS-52
PS2-61
PS2-61P
PS5-1
PS6-2
Notice that hyphens are not ignored and are used as part of the sort
Any help would be great
Gerard Iannuzzelli
giannuzzelli@covad.net
|
|
|
|
|
For strings ListViewSortManager just uses String.CompareTo() which performs a word (case-sensitive and culture-sensitive) comparison using the current culture. So if your current culture gives a special meaning to hyphens you'll see this unexpected behavior. If you want to modify this behavior, derive a class from ListViewTextSort and override the OnCompare() method.
Hope this helps,
Eddie
A complex system that does not work is invariably found to have evolved from a simpler system that worked just fine. - Murphy's Law of Computing
|
|
|
|
|
First I'd like to say GREAT JOB Eddie!
Stopping paint also makes column sorting faster..
Works great for me since I'm using different backcolor's on rows...
private void ColumnClick(object sender, ColumnClickEventArgs e)
{
// Faster sorting
m_list.BeginUpdate();
this.Sort(e.Column);
m_list.EndUpdate();
}
id10t
|
|
|
|
|
Thanks! I'm glad to hear that you find this control useful.
I'll try to incorporate your suggestion soon.
A complex system that does not work is invariably found to have evolved from a simpler system that worked just fine. - Murphy's Law of Computing
|
|
|
|
|
Hi,
Can someone pls explain to me the details of this line of code:
ListViewTextSort comp = (ListViewTextSort) Activator.CreateInstance(m_comparers[m_column], ....dadada);
I can kinda make out from some reading that it is a generic constructor caller. But why do we really need it and what is its function?
Basically my problem is I have 2 columns(in future no. of columns will chg programatically). One of the columns is Name and other is Date. But I am kind of treating both of them as simple strings. Hence I am ok with the simplest comparer -viz. ListViewTextSort for both the columns. It does well for me. So I wrote code which looks like:
<br />
m_sortMgr = new ListViewSortManager(my_view,new Type[] {typeof(ListViewTextSort)}, 0,SortOrder.Ascending);<br />
....
....
And my Sort() func in ListViewManager.cs looks like:
<br />
public void Sort(Int32 column, SortOrder order)<br />
{<br />
if(column < 0)
throw new IndexOutOfRangeException();<br />
Also in ListViewSortManager.cs, I commented out all the other (derived)comparers which I am not using.
On doing this sorting works fine for the first column(Name), but whenever I click the second column(Date) I get an exception, that says, index out of bounds, at the above "Activator.CreateInstance()" call.
I figured out the sol'n(not sure if its right) by providing the same comparer 4 times in my def'n to:
<br />
m_sortMgr = new ListViewSortManager(my_view,new Type[] {typeof(ListViewTextSort), typeof(ListViewTextSort),typeof(ListViewTextSort), typeof(ListViewTextSort)},0, SortOrder.Ascending);<br />
With this sorting works fine for both columns. But I am still not clear, how this works.
I have foll questions:
1) Someone pls explain me the detail/need of this Activator.CreateInstance() call and the corresponding 4 entries I have to provide in my workaround def'n of "m_sortMgr" for each comparer, even if all of them are same.
2) In future, when my number of my columns are going to be changing programatically, will I have to assign comparers to them dynamically ? how ?
3) On debugging the sample demo, I never hit the breakpoint for these two funcs - GetColumnComparerType() & SetColumnComparerType(). When/where are these functions used ? their purpose ?
Thanks.
|
|
|
|
|
1) The ListViewSortManager saves the type of the comparers to be used for each column, so the call to Activator.CreateInstance() creates an instance of the particular comparer that will be used by the list view.
2) Assign a new array of comparers with a call to SetComparerTypes() .
3) GetColumnComparerType() and SetColumnComparerType() are helper methods that let you get or set the type of the comparer used by the specified column. The are not used internally by ListViewSortManager , the are intended to be used by the client code if needed.
E_NoName wrote:
m_sortMgr = new ListViewSortManager(my_view,new Type[] {typeof(ListViewTextSort)}, 0,SortOrder.Ascending);
The comparers array needed one entry per-column in the ListView, so this code will only work for single-column lists. To avoid the IndexOutOfRangeException , add one entry in the comparer array for each column.
A complex system that does not work is invariably found to have evolved from a simpler system that worked just fine. - Murphy's Law of Computing
|
|
|
|