Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / January 2008

Tip: Looking for answers? Try searching our database.

ListView column header text on column resizing?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Walter Sobchak - 15 Jan 2008 08:28 GMT
I have a listview control with a couple of columns. Sort order is
indicated with a litle triangle.
The problem is when the sorted column is resized to a smaller width the
text is shortened and there are 3 dots displayed at the end.
The dots are bellow the triangle so I'd like to delete the dots or make
the shortening of text happen earlier.

Thanks for any help.

p.s.
I tried cutting the text on columnwidthchanging event but it doesn't
alwasy work ok (sometimes when one char is left displayed the column
text variable is containing zero chars).
Claes Bergefall - 15 Jan 2008 11:05 GMT
How are you putting the image in the column?

I tried my own control I've written and it doesn't experience the problem
you're describing. It uses an image list and with the standard properties on
the ColumnHeader class (i.e ImageIndex) the image ends up on the left side
of the text. In this case there obviously aren't any dots under the image.
Some tweaking with P/Invoke puts the image to the right of the text, but the
dots are still drawn to the left of the text. Not sure why you get the dots
drawn underneath the image.

Can you show a short sample to reproduce what you're seeing?

  /claes

>I have a listview control with a couple of columns. Sort order is indicated
>with a litle triangle.
[quoted text clipped - 9 lines]
> alwasy work ok (sometimes when one char is left displayed the column text
> variable is containing zero chars).
Walter Sobchak - 15 Jan 2008 11:43 GMT
This happens because I am using Graphics to draw the triangle after I
compute where to put it.
I'll try to do it that way.
I guess you are using your own and not system images?

> How are you putting the image in the column?
>
[quoted text clipped - 23 lines]
>> alwasy work ok (sometimes when one char is left displayed the column text
>> variable is containing zero chars).
Claes Bergefall - 15 Jan 2008 14:55 GMT
Yes, I draw my own images and put them in an imagelist. Then assign the
imagelist to the ListView.SmallImageList

There doesn't seem to be a .NET way to right align the image though, so
you'll have to use some P/Invoke
1. Use LVM_GETHEADER to get a handle to the column header control
2. Use HDM_SETITEM to set a new format flag (the fmt member in the HDITEM
structure)) that includes HDF_BITMAP_ON_RIGHT
You should only need to do this once upon startup

Here's the code I use to create the image list with the arrows in it. It's
in VB.NET though, but should be easy to understand:

Private Function CreateSortingImages() As ImageList
   Dim imgList As New ImageList
   Dim imgUpArrow As New Bitmap(16, 16,
Drawing.Imaging.PixelFormat.Format32bppArgb)
   Dim imgDownArrow As New Bitmap(16, 16,
Drawing.Imaging.PixelFormat.Format32bppArgb)
   imgList.ImageSize = New Size(16, 16)
   imgList.ColorDepth = ColorDepth.Depth8Bit
   imgList.TransparentColor = SystemColors.Desktop

   Dim penLeft As New Pen(SystemColors.ControlDark, 1)
   Dim penRight As New Pen(SystemColors.ControlLightLight, 1)
   Dim brushBackground As New SolidBrush(SystemColors.Control)
   Dim brushTransparent As New SolidBrush(SystemColors.Desktop)
   Dim dc As Graphics
   Dim point1 As Point
   Dim point2 As Point
   Dim point3 As Point
   Dim point4 As Point
   Dim point5 As Point
   Dim point6 As Point

   ' Up arrow image - Index 0
   dc = Graphics.FromImage(imgUpArrow)
   dc.FillRectangle(brushTransparent, 0, 0, 16, 16)
   point1 = New Point(7, 5)
   point2 = New Point(8, 5)
   point3 = New Point(11, 10)
   point4 = New Point(11, 11)
   point5 = New Point(4, 11)
   point6 = New Point(4, 10)
   dc.FillPolygon(brushBackground, New Point() {point1, point2, point3,
point4, point5, point6})
   dc.DrawLine(penLeft, point6, point1)
   dc.DrawLine(penRight, point2, point3)
   dc.DrawLine(penRight, point4, point5)
   imgList.Images.Add(imgUpArrow, SystemColors.Desktop)

   ' Down arrow image - Index 1
   dc = Graphics.FromImage(imgDownArrow)
   dc.FillRectangle(brushTransparent, 0, 0, 16, 16)
   point1 = New Point(4, 4)
   point2 = New Point(11, 4)
   point3 = New Point(11, 5)
   point4 = New Point(8, 10)
   point5 = New Point(7, 10)
   point6 = New Point(4, 5)
   dc.FillPolygon(brushBackground, New Point() {point1, point2, point3,
point4, point5, point6})
   dc.DrawLine(penLeft, point1, point2)
   dc.DrawLine(penRight, point2, point4)
   dc.DrawLine(penLeft, point5, point6)
   imgList.Images.Add(imgDownArrow, SystemColors.Desktop)

   Return imgList
End Function

   /claes

> This happens because I am using Graphics to draw the triangle after I
> compute where to put it.
[quoted text clipped - 28 lines]
>>> alwasy work ok (sometimes when one char is left displayed the column
>>> text variable is containing zero chars).
Walter Sobchak - 18 Jan 2008 14:32 GMT
Thanks for your help.
So far I used this code to initialize the image list:

IntPtr hc;

// Get a handle to the header control.
hc = Win32.SendMessage(aControl.Handle, Win32.LVM_GETHEADER, (UInt32)0,
(UInt32)0);

// Add the image list to the header control.
Win32.SendMessage(hc, Win32.HDM_SETIMAGELIST, (UInt32)0,
(UInt32)CreateSortingImages().Handle);

Now when I want to display an arrow I tried to use something like
lv.Columns[0].ImageIndex = 1;

But it doesn't work.
Can you show me your code for changing imageindex?
I don't know what I am doing wrong.

> Yes, I draw my own images and put them in an imagelist. Then assign the
> imagelist to the ListView.SmallImageList
[quoted text clipped - 100 lines]
>>>> alwasy work ok (sometimes when one char is left displayed the column
>>>> text variable is containing zero chars).
Walter Sobchak - 18 Jan 2008 14:49 GMT
Now I tried to set the imagelist to the listview instead of the column
header and it works. The problem is that I already have one imagelist
associated with the listview.
So I should be able to associate 2 image lists to listview or associate
one to the column header..

> Thanks for your help.
> So far I used this code to initialize the image list:
[quoted text clipped - 15 lines]
> Can you show me your code for changing imageindex?
> I don't know what I am doing wrong.
Walter Sobchak - 18 Jan 2008 15:37 GMT
> Thanks for your help.
> So far I used this code to initialize the image list:
[quoted text clipped - 8 lines]
> Win32.SendMessage(hc, Win32.HDM_SETIMAGELIST, (UInt32)0,
> (UInt32)CreateSortingImages().Handle);

Setting the imagelist to column header is the right thing to do.
The problem was that I didn't set the imageindex correctly.
This works:

 for (int i = 0; i < lv.Columns.Count; i++)
                {
                    // Use the LVM_SETCOLUMN message to set the
column's image index.
                    Win32.LVCOLUMN col;
                    //  col.mask: include LVCF_FMT | LVCF_IMAGE
                    col.mask = Win32.LVCF_FMT | Win32.LVCF_IMAGE;

                    // LVCFMT_IMAGE
                    //col.fmt = Win32.LVCFMT_IMAGE;
                    col.fmt = Win32.LVCFMT_IMAGE |
Win32.HDF_BITMAP_ON_RIGHT;

                    // The image to use from the image list.

                    if (ColumnToSort == i)
                    {
                        if (OrderOfSort == SortOrder.Ascending)
                        {
                            col.iImage = 0;
                        }
                        else
                        {
                            col.iImage = 1;
                        }
                    }
                    else
                        col.iImage = -1;

                    //  Initialize the rest to zero.
                    col.pszText = (IntPtr)0;
                    col.cchTextMax = 0;
                    col.cx = 0;
                    col.iSubItem = 0;
                    col.iOrder = 0;

                    // Send the LVM_SETCOLUMN message.
                    // The column that we are assigning the image to is
defined in the third parameter.
                    Win32.SendMessage(lv.Handle, Win32.LVM_SETCOLUMN,
(UInt32)i, ref col);
                }

Claes, thank you very much for your help.
Claes Bergefall - 21 Jan 2008 10:19 GMT
Using the ColumnHeader.ImageIndex property apparently doesn't work as you
found out. The code I have was written for 1.1 where that property doesn't
exist, so it uses the exact same technique as you've shown below. Since that
still works I haven't bothered investigating why the .NET property doesn't
behave as expected (maybe someday I'll be bored enough to find out why :-)).

Anyway, glad to see you have a working solution.

  /claes

>> Thanks for your help.
>> So far I used this code to initialize the image list:
[quoted text clipped - 57 lines]
>
> Claes, thank you very much for your help.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.