Simon
Simon

Reputation: 26013

How do I set an image for some but not all nodes in a TreeView?

I have a TreeView windows forms control with an ImageList, and I want some of the nodes to display images, but the others to not have images.

I don't want a blank space where the image should be. I don't want an image that looks like the lines that the TreeView would draw if it didn't have an ImageList. How do I get it to draw images for some items and not others, without resorting to clumsy hacks like that?

Upvotes: 22

Views: 39514

Answers (7)

Greg Sipes
Greg Sipes

Reputation: 703

I ran into this issue and solved it by iterating the nodes that I wanted to have no icon and setting the ImageIndex and SelectedImageIndex properties to values higher than the ImageList AFTER all of the nodes had been already been added to the TreeView. Setting these properties before all of the other nodes were added resulted in only the first one not having the icon.

Upvotes: 0

Aussie Ash
Aussie Ash

Reputation: 1346

I found that using StateImageList on the TreeView instead of ImageList will only show the image when StateImageIndex on the TreeNode is equal or greater than 0

Upvotes: 13

Rogerio Souza
Rogerio Souza

Reputation: 139

Hei bro, i found a way. Set the first image as an empty image, like this...

TreeView treeView = new TreeView();
treeView.ImageList.Images.Add(new Bitmap(1,1));

So, the index 0 is an empty image. I hope this helps

Upvotes: 0

Martin Brown
Martin Brown

Reputation: 25329

I tried this once and I don't think it is possible.

If you try to set both ImageKey and ImageIndex to "not set" values the control just defaults ImageIndex to 0. The following code:

treeView.ImageKey = "Value";
Debug.WriteLine(treeView.ImageIndex);
treeView.ImageKey = null;
Debug.WriteLine(treeView.ImageIndex);
treeView.ImageIndex = -1;
Debug.WriteLine(treeView.ImageIndex);

Produces output:

-1
0
0

This kind of tells you that the control developers wanted to make sure that there was always a default image. That just leaves you with the hack options I'm afraid.

Upvotes: 8

John Fischer
John Fischer

Reputation: 1125

You need to set ImageIndex and SelectedImageIndex to a number that is higher than the number of values in your ImageList. For example, if you create this node and add it to your TreeView:

TreeNode node1 = new TreeNode(string.Empty, 12, 12); // imageList1.Count = 5

you will have an invisible TreeNode inserted into your TreeView. I changed the background color of my TreeView and it was still invisible.

(I googled this for some time, and I eventually found the answer here: http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.windowsforms/2006-09/msg00322.html)

Upvotes: 12

MtnManChris
MtnManChris

Reputation: 536

What I have chosen to do is to use an image of dots for those TreeView nodes that are not supposed to have an image.

TreeNode with image dots

I add this image as the last image in the list, and if the item is not supposed to have an image I set it to ImageList.Images.Count-1

Upvotes: 11

user1887120
user1887120

Reputation: 146

This will draw the TreeNode text where the image should have been, getting rid of the white space.

You'll need to set the TreeView's DrawMode property to OwnerDrawText. You can find the DrawMode property in the properties panel.

Next when you add a node, set it's ImageIndex and SelectedImageIndex greater than the value of your yourImageListName.Images.Count value. This is so no image will be drawn, but there will still be that white space you don't want.

Now to get rid the white space. Add a handle for the treeviews DrawNode event. This can be done by going to the treeviews property panel and clicking the Icon in the panel that looks like a lighting bolt, then scroll till you see the text DrawNode, double click it.

Now you just copy and paste this into the created method

if (e.Node.ImageIndex >= e.Node.TreeView.ImageList.Images.Count) // if there is no image
{
    int imagewidths = e.Node.TreeView.ImageList.ImageSize.Width;
    int textheight = TextRenderer.MeasureText(e.Node.Text, e.Node.NodeFont).Height;
    int x = e.Node.Bounds.Left - 3 - imagewidths / 2;
    int y = (e.Bounds.Top + e.Bounds.Bottom) / 2+1;

    Point point = new Point(x - imagewidths/2, y - textheight/2); // the new location for the text to be drawn

    TextRenderer.DrawText(e.Graphics, e.Node.Text, e.Node.NodeFont, point, e.Node.ForeColor);
}
else // drawn at the default location
    TextRenderer.DrawText(e.Graphics, e.Node.Text, e.Node.TreeView.Font, e.Bounds, e.Node.ForeColor);

Upvotes: 3

Related Questions