|
Go figure - I spend a couple hours last night on this and right after I posted the previous message, a thought hit me. I checked the messages for setting the ImageList for a ListView and the header control and they're the same. I know that a lot of controls pass their messages down to their children, so the the same ImageList was being set on the header control as well. If I set the ImageList for the ListView first, then the header control, all is well.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
I have a weird problem. I have a listview that uses icons. So I have the listview small and large icons lists set. Now it appears that the ShowHeaderIcon's are no longer the arrows, but the icons from my image lists.
Is there an easy work around for this?
Thanks
KW
|
|
|
|
|
I haven't seen this happen. However, if you set the imagelist of the list's header control to your imagelist this is the behavior that you'll observe.
Do you have a small sample app that replicates this behavior?
If Java had true garbage collection, most programs would delete themselves upon execution - Robert Sewell
|
|
|
|
|
That is exactly what I am doing. I am using my own image lists. I several listviews within the software that pull from the same 16x16 and 32x32 image lists. As a temporary work around I just found some up and down arrow icons and added them as the first two images in my image lists.
I wasnt sure is there was a way to modify your code so the arrows you are creating internally are not using listview's image list property for storage.
Thanks,
KW
|
|
|
|
|
Anonymous wrote:
That is exactly what I am doing. I am using my own image lists
This I know, what I said was "if you set the imagelist of the list's header control to your imagelist". What I don't know is if the list control resets the image list of the header control whenever it's image list is changed. (Which seems to be the problem by the way)
If Java had true garbage collection, most programs would delete themselves upon execution - Robert Sewell
|
|
|
|
|
No I only specify the small and large lists. Sorry I miss-understood you.
|
|
|
|
|
I have a similar problem, I add icons to the listview (dynamicly using this code http://www.vbaccelerator.com/home/NET/Code/Libraries/Shell_Projects/SysImageList/article.asp ), however using this technique my sort icons get replaced by those in the ImageList of the ListView. At this point I don't know if it's an error on the library,your control or my code.
|
|
|
|
|
The work around I came up with for this problem was to find my own "up" and "down" arrow icons (or gif's with transparent background) and add them as the first two images in you image list(s).
Hope this helps,
kWa
|
|
|
|
|
As stated above, I'm using the http://www.vbaccelerator.com/home/NET/Code/Libraries/Shell_Projects/SysImageList/article.asp library to create dinamicaly icons for the list. This library fools the control in thinking it has a Imagelist but i don't know if it really exist since (if I understand it correctly, I'm not into unmanaged code) it seems to work with handles which are not icons...
How does this blend with your methods that create the up-down arrows?
Could the up-down arrow methods be extracted from your code? If so how?
Does someone think it's possible to adapt the library from above so it would know to create those arrows in the right posision? The strangest thing is that for me the effect is to show the shared-folder-on-network and shortcut icon's which are not supposed to be generated by the library (or maybe it gives those icons for 0 and 1 as indexers (can one say that for unmanaged c++)?
|
|
|
|
|
I found if I add the following method to the ListViewSortManager class and call it any time I update the imagelists, it works fine:
public void SetHeaderImageList()
{
SetHeaderImageList(this.m_list, this.m_imgList);
}
It's a real shame that the standard ListView doesn't have events for changing imagelists otherwise you could register for it like the column click and handle it automatically.
|
|
|
|
|
You must place creating ListViewSortManager on form_load event, not in form constructor. That helps me.
|
|
|
|
|
Just what the doctor ordered.
|
|
|
|
|
pbible wrote:
Just what the doctor ordered
Thank you!
The nice thing about C++ is that only your friends can handle your private parts.
|
|
|
|
|
Hi,
I have a ListView with alternate row colors! After sorting a column, the rows colors appear mixed
Is there a way to exented this nice class to handle this problem?
Eddie, thanks for yor nice class!
Max Glaser
Email: MaxGlaser@gmx.net
|
|
|
|
|
GlaserSoft wrote:
I have a ListView with alternate row colors! After sorting a column, the rows colors appear mixed... Is there a way to exented this nice class to handle this problem?
I had the same issue and extended the class to add an event to be raised after each sort is complete. Then I could just add a listener to the event to call a method which sets the background colors on this ListView each time a sort occurs.
The only change necessary to Eddie's code is to mark as virtual the method public void Sort(Int32 column, SortOrder order)
Here's my code:
using System;
using System.Windows.Forms;
namespace MyApplication
{
public class EventRaisingSortManager : EV.Windows.Forms.ListViewSortManager
{
public EventRaisingSortManager(ListView list, Type[] comparers) :
base(list, comparers)
{
}
public override void Sort(Int32 column, SortOrder order)
{
base.Sort(column,order);
OnSorted(column,order);
}
private void OnSorted(Int32 column, SortOrder order)
{
if (Sorted != null)
Sorted(this,new SortedEventArgs(column,order));
}
public event SortedEvent Sorted;
}
public delegate void SortedEvent(object sender, SortedEventArgs e);
public class SortedEventArgs : System.EventArgs
{
int _column;
SortOrder _order;
public SortedEventArgs(Int32 column, SortOrder order) : base()
{
this._column = column;
this._order = order;
}
public Int32 Column
{
get { return _column; }
set { _column = value; }
}
public SortOrder Order
{
get { return _order; }
set { _order = value; }
}
}
}
|
|
|
|
|
Hi Eddie
I like your code, but I would like to send you a change I made:
I created a date column, and the sorting crashed the program because my dates were not in a proper date-time format.
So I modified the OnCompare of each class like so:
private bool m_SortError=false;
protected override Int32 OnCompare(String lhs, String rhs)
{ //Error-handling added by Willem Semmelink
if (m_SortError) return 0; // dont show error message for each row
else {
try { // insert here Eddie's original code - int/date/string compare as the case may be
return DateTime.Parse(lhs).CompareTo(DateTime.Parse(rhs));
} catch(Exception E) {
m_SortError=true;
MessageBox.Show(E.Message);
}
return 0;
}
}
Perhaps, in stead of repeating this code in each OnCompare method, I should have followed a true O-O design and modified the base class, but this works for me.
Now, instead of crashing the application, I show the error to the user, and let him/her continue.
Just thought you may find it useful, too.
Greetings,
Willem Semmelink
|
|
|
|
|
WillemSe wrote:
and the sorting crashed the program because my dates were not in a proper date-time format. So I modified the OnCompare of each class like so:
I thought about adding something similar but dropped the idea because I think that ill-formed data shouldn't be allowed to be inserted in the list in the first place. Besides, all the checks would impose a large overhead to the sort process.
WillemSe wrote:
Perhaps, in stead of repeating this code in each OnCompare method, I should have followed a true O-O design and modified the base class, but this works for me.
I think you meant: create a derived class and add the extended functionality there.
There are only 10 kind of people in the world: those who understand binary and those who don't.
|
|
|
|
|
re:
//I think you meant: create a derived class and add the extended functionality there.
no, what I meant is that I would have liked to modify only ListViewTextSort whilst in the current implementation, I added the try..catch in each class:
* ListViewTextSort;
* ListViewTextCaseInsensitiveSort;
* ListViewDateSort;
* ListViewInt32Sort;
* ListViewInt64Sort;
* ...
I meant that I would have liked to implement error-checking only in ListViewTextSort so the others could inherit it - but it was easier to duplicate the code in each subclass.
The reason why the date failed on me was probably due to culture information - feeding a date in a non-American date format. So I will maybe spend some more time on it later to add culture info: I would like to do the comparison somewhat like this:
return DateTime.Parse(lhs,m_dateFormat,System.Globalization.DateTimeStyles.NoCurrentDateDefault).CompareTo(
DateTime.Parse(rhs,m_dateFormat,System.Globalization.DateTimeStyles.NoCurrentDateDefault));
where dateFormat is a System.Globalization.CultureInfo.
This will give me the control to determine whether the dates are in "dd-mm-yyyy", "mm-dd-yyyy", or "yyyy-mm-dd".
re:
//I think that ill-formed data shouldn't be allowed to be inserted in the list in the first place.
I agree, but in my experience, what should happen and what actually happens in a development environment are not the same.
Greetings
Willem Semmelink
|
|
|
|
|
WillemSe wrote:
//I think you meant: create a derived class and add the extended functionality there.
no, what I meant is that I would have liked to modify only ListViewTextSort whilst in the current implementation
Well, what I really meant is that the OOP way is to derive a class, not to modify the base class. Now, in the real world you have the base class code so you can do change it to suit you needs.
WillemSe wrote:
The reason why the date failed on me was probably due to culture information - feeding a date in a non-American date format.
I agree that the predefined sorters for dates and numbers aren't culture friendly. This has to change.
WillemSe wrote:
I agree, but in my experience, what should happen and what actually happens in a development environment are not the same.
This is true, but I don't think it is an excuse for allowing "invalid" data to get in the system. Now, because the date sorter is culture-agnostic, your perfectly valid dates (in you culture) are considered invalid in the sorter. You have two options:- Format the data according to the needs of the sorter and make you users unhappy (not very attractive)
- Change the sorter to accept dates expressed according to different cultural requirements. (This is the obvious and best solution)
This is why I believe that adding code to sorter to validate the dates is not the best solution, making the sorter culture-aware is. I'll check it out and thank you for bringing this to my attention.
There are only 10 kind of people in the world: those who understand binary and those who don't.
|
|
|
|
|
Eddie wrote:
I'll check it out and thank you for bringing this to my attention.
I am happy if I could contribute something. Thanks for pointing out to me the performance implications.
Best wishes
Willem
|
|
|
|
|
I can't seem to get the class to work right if the column width is preset to -1 or -2. It just resizes the column wide enough for the column label. Have you run into this problem
|
|
|
|
|
Great addition. Your listview sorter is easy to use, fast, and exactly what I needed. Thanks!
- Scott
|
|
|
|
|
I'm glad you liked it.
There are only 10 kind of people in the world: those who understand binary and those who don't.
|
|
|
|
|
TextAlign seems to be forced to the Left after you order by a column. Fix within ShowHeaderIcon is something like :
if (columnIndex < 0)
hd.fmt = HDF_LEFT | HDF_STRING | HDF_BITMAP_ON_RIGHT;
else if (list.Columns[columnIndex].TextAlign == HorizontalAlignment.Left)
hd.fmt = HDF_LEFT | HDF_STRING | HDF_BITMAP_ON_RIGHT;
else if (list.Columns[columnIndex].TextAlign == HorizontalAlignment.Center)
hd.fmt = HDF_CENTER | HDF_STRING | HDF_BITMAP_ON_RIGHT;
else
hd.fmt = HDF_RIGHT | HDF_BITMAP_ON_RIGHT | HDF_STRING;
although I'm no expert - I'd prefer it if the bitmap is displayed on the left on a right-aligned column.
JwB
|
|
|
|
|
Yes, it is a bug. I'll fix it as soon as I have a chance (probably this weekend). Your proposed solution works ok, however I would like to make a generic fix: allow the user to set the bitmap alignment, something like a new BitmapAlign property or something.
There are only 10 kind of people in the world: those who understand binary and those who don't.
|
|
|
|