Display thumbnails of 128x128 pixels or more in the grid in ListView

Original question (see Update below)

I have a WinForms program that needs a decent scrollable icon control with large icons (in fact, the size of the icon is 128x128 or more), which you can click halfway around or double click to perform an action. It is preferable that there is minimal wasted space (under each icon short file headers might be required; if the file name is too long, I can add an ellipsis).

finished version of listview with proper colors, spacing, etc.
(source: updike.org )

I tried using ListView with LargeIcon (default .View) and the results are disappointing:

screenshot showing tiny icons in LargeIcon view
(source: updike.org )

Perhaps I'm filling in the control incorrectly? The code:

ImageList ilist = new ImageList(); this.listView.LargeImageList = ilist; int i = 0; foreach (GradorCacheFile gcf in gc.files) { Bitmap b = gcf.image128; ilist.Images.Add(b); ListViewItem lvi = new ListViewItem("text"); lvi.ImageIndex = i; this.listView.Items.Add(lvi); i++; } 

I need large icons with a little empty space, not a big empty space with embarrassingly small icons.

  1. Is there a .NET control that does what I need?
    • Is there a favorite third-party control that does this?
    • If not, what control is best inherited and configured to make it work?
    • Should I break down and create my own control (with which I have a lot of experience ... I just do not want to go to such an extreme state, as this is somewhat connected).

I found this tutorial about OwnerDraw, but working with it is basically 3 or 4 above, as this demo just shows how to animate the lines in a detailed view.

Refresh

Adding a line

 ilist.ImageSize = new Size(128, 128); 

before the for loop fixed the size problem, but now the images are paletted to 8-bit (looks like system colors?), although the debugger shows that the images are inserted into ImageList as 24bpp System.Drawing.Bitmap's:

large icons, finally
(source: updike.org )

  1. How can I (can I?) Force images to display in full 24-bit color?
    • The spacing between the icons is still pretty wasteful ... how to fix it? May I?

Update 2

Together with the addition of a line

 ilist.ColorDepth = ColorDepth.Depth24Bit; 

Then, after setting ilist.ImageSize, I followed the advice of the arbiter and changed the interval:

 [DllImport("user32.dll")] public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); public int MakeLong(short lowPart, short highPart) { return (int)(((ushort)lowPart) | (uint)(highPart << 16)); } public void ListView_SetSpacing(ListView listview, short cx, short cy) { const int LVM_FIRST = 0x1000; const int LVM_SETICONSPACING = LVM_FIRST + 53; // http://msdn.microsoft.com/en-us/library/bb761176(VS.85).aspx // minimum spacing = 4 SendMessage(listview.Handle, LVM_SETICONSPACING, IntPtr.Zero, (IntPtr)MakeLong(cx, cy)); // http://msdn.microsoft.com/en-us/library/bb775085(VS.85).aspx // DOESN'T WORK! // can't find ListView_SetIconSpacing in dll comctl32.dll //ListView_SetIconSpacing(listView.Handle, 5, 5); } /////////////////////////////////////////////////////////// ListView_SetSpacing(this.listView, 128 + 12, 128 + 4 + 20); 

The ListView control may not be ideal or have default values, as I expected (for example, the Spacing property), but I'm glad I could tame it at the end:

alt text
(source: updike.org )

By the way, in order to maintain the correct aspect ratio for the thumbnails, I needed to create my own 128x128 bitmaps, clear the background to fit the control, and center these images:

 public void CenterDrawImage(Bitmap target, Color background, Bitmap centerme) { Graphics g = Graphics.FromImage(target); g.Clear(background); int x = (target.Width - centerme.Width) / 2; int y = (target.Height - centerme.Height) / 2; g.DrawImage(centerme, x, y); g.Dispose(); } 
+44
c # listview winforms thumbnails
Jul 08 '09 at 23:47
source share
5 answers

To update:

  • Set the color depth of the image list in addition to the image size (ilist.ColorDepth = ColorDepth.Depth24Bit)
  • WinForms ListView does not have the ability to change the distance between the icons, however it can be easily done using Win32. You need to send LVM_SETICONSPACING to your ListView (there are many guides for using the SendMessage win32 function in .net, so I think that this should be enough for you).
+13
Jul 09 '09 at 8:40
source share

You can use FlowLayoutPanel and crop graphic boxes in it. Set the image size to 128x128, and sizemode to β€œzoom” (this will allow you to resize the image without losing the aspect ratio). You can even add images programmatically.

 PictureBox pb = New Picturebox; pb.image = gcf.image128; FlowLayoutPanel1.Controls.Add(pb) 

Since you need to have a shortcut under the image, you can create a Usercontrol, as the pastor said that all he has is a subcategory and a shortcut. Then it will be a control instance that you would add to your flowlayout panel.

+5
Jul 09 '09 at 0:19
source share

ObjectListView (an open source wrapper around the .NET ListView) makes it easy to customize the Tile view. Look at the Complex view in the demo, switch to the Tile view when the user rally is on: the owner handles the tile image http://objectlistview.sourceforge.net/cs/_images/tileview-ownerdrawn.png

If you only need a 128x128 image plus some text data, you don’t even need to draw it. You could give it a big muesli, and then mark which pieces of textual information you want to display on the Tile using IsTileViewColumn.

+5
Jul 13 '09 at 9:07
source share

Disclaimer: I work for Atalasoft

Our .NET Imaging SDK has an image thumbnail control, DotImage

+2
Jul 09 '09 at 0:23
source share

Creating a custom control will not be too bad. I would inherit from Panel or Usercontrol, since I think it automatically adds scrollbars for content.

Dynamically adding containers (e.g. PictureBoxes) and captions for each image, handling a mousedown or mouseclick event for a container, and possibly drawing a red square around it to show that it is selected. The "hardest" part is to resample the image to 128x128 if they are not of the same size, and even this can be easy with GDI +.

+1
Jul 09 '09 at 0:03
source share



All Articles