Reputation: 2093
I have a treeview and a imageList which contain 1 icon (folder.ico), I want to set icon only for root node, child node will don't have icon, so I try to set image index for child node but it have some problem, look the picture:
My code:
ImageList imageList = new ImageList();
imageList.Images.Add(Image.FromFile(System.AppDomain.CurrentDomain.BaseDirectory.Replace("\\bin\\Debug\\","") + "\\Images\\folder.ico"), Color.Transparent);
treeView1.ImageList = imageList;
foreach (TreeNode node in treeView1.Nodes)
{
foreach (TreeNode node2 in node.Nodes)
{
node2.ImageIndex = 100;
node2.SelectedImageIndex = 100;
}
}
Thanks
EDIT I create a Custom TreeView at the answer of @Killercam:
class CustomTreeView : TreeView
{
public const int NOIMAGE = -1;
public CustomTreeView()
: base()
{
// .NET Bug: Unless LineColor is set, Win32 treeview returns -1 (default), .NET returns Color.Black!
base.LineColor = SystemColors.GrayText;
base.DrawMode = TreeViewDrawMode.OwnerDrawAll;
}
protected override void OnDrawNode(DrawTreeNodeEventArgs e)
{
// Space between Image and Label.
const int SPACE_IL = 3;
// We only do additional drawing.
e.DrawDefault = true;
base.OnDrawNode(e);
if (base.ShowLines && base.ImageList != null && e.Node.ImageIndex == NOIMAGE
// exclude root nodes, if root lines are disabled
//&& (base.ShowRootLines || e.Node.Level > 0))
)
{
// Using lines & images, but this node has none: fill up missing treelines
// Image size
int imgW = base.ImageList.ImageSize.Width;
int imgH = base.ImageList.ImageSize.Height;
// Image center
int xPos = e.Node.Bounds.Left - SPACE_IL - imgW / 2;
int yPos = (e.Node.Bounds.Top + e.Node.Bounds.Bottom) / 2;
// Image rect
Rectangle imgRect = new Rectangle(xPos, yPos, 0, 0);
imgRect.Inflate(imgW / 2, imgH / 2);
using (Pen p = new Pen(base.LineColor, 1))
{
p.DashStyle = DashStyle.Dot;
// Account uneven Indent for both lines.
p.DashOffset = base.Indent % 2;
// Horizontal treeline across width of image
// account uneven half of delta ItemHeight & ImageHeight.
int yHor = yPos + ((base.ItemHeight - imgRect.Height) / 2) % 2;
//if (base.ShowRootLines || e.Node.Level > 0)
//{
// e.Graphics.DrawLine(p, imgRect.Left, yHor, imgRect.Right, yHor);
//}
//else
//{
// // for root nodes, if root lines are disabled, start at center
// e.Graphics.DrawLine(p, xPos - (int)p.DashOffset, yHor, imgRect.Right, yHor);
//}
e.Graphics.DrawLine(p,
(base.ShowRootLines || e.Node.Level > 0) ? imgRect.Left : xPos - (int)p.DashOffset,
yHor, imgRect.Right, yHor);
if (!base.CheckBoxes && e.Node.IsExpanded)
{
// Vertical treeline , offspring from NodeImage center to e.Node.Bounds.Bottom
// yStartPos: account uneven Indent and uneven half of delta ItemHeight & ImageHeight
int yVer = yHor + (int)p.DashOffset;
e.Graphics.DrawLine(p, xPos, yVer, xPos, e.Node.Bounds.Bottom);
}
}
}
}
protected override void OnAfterCollapse(TreeViewEventArgs e)
{
base.OnAfterCollapse(e);
if (!base.CheckBoxes && base.ImageList != null && e.Node.ImageIndex == NOIMAGE)
{
// DrawNode event not raised: redraw node with collapsed treeline
base.Invalidate(e.Node.Bounds);
}
}
}
Then use it in my code:
private void TestCustomTreeView_Load(object sender, EventArgs e)
{
// @Killercam EDIT: Set the default Image to one that is not used.
valForm.siteTreeView.ImageIndex = 100;
valForm.siteTreeView.SelectedImageIndex = 100;
TemplateCustomTreeView myTree = new TemplateCustomTreeView();
myTree.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
myTree.Location = new System.Drawing.Point(6, 26);
myTree.Name = "tree";
myTree.Scrollable = true;
myTree.Size = new System.Drawing.Size(320, 296);
myTree.ImageList = imageList1;
/*Add item*/
TreeNode node = new TreeNode();
node.Name = "abc1";
node.Text = "abc1";
node.ImageIndex = 0;
myTree.Nodes.Add(node);
TreeNode node3 = new TreeNode();
node3.Name = "abc2";
node3.Text = "abc2";
node3.ImageIndex = -1;
node.Nodes.Add(node3);
////
TreeNode node2 = new TreeNode();
node2.Name = "abc3";
node2.Text = "abc3";
node2.ImageIndex = 0;
myTree.Nodes.Add(node2);
this.Controls.AddRange(new System.Windows.Forms.Control[] { myTree });
}
}
The result still not work, It's still have a folder icon before the text!
Upvotes: 2
Views: 11585
Reputation: 13
Tried using a blank image file?
(Or one that only contains the horizontal stippled line, or an arrow...)
Upvotes: 0
Reputation: 23831
You can't do what you require
"All I want is don't show icon at child node."
without overriding the control. I also have found that you cannot display different images for different nodes with the standard WinForms TreeView
. Below is some code that will make the TreeView look better; that is will draw the small section of the tree line for the sub-nodes.
class CustomTreeView : TreeView
{
public const int NOIMAGE = -1;
public CustomTreeView()
: base()
{
// .NET Bug: Unless LineColor is set, Win32 treeview returns -1 (default), .NET returns Color.Black!
base.LineColor = SystemColors.GrayText;
base.DrawMode = TreeViewDrawMode.OwnerDrawAll;
}
protected override void OnDrawNode(DrawTreeNodeEventArgs e)
{
// Space between Image and Label.
const int SPACE_IL = 3;
// We only do additional drawing.
e.DrawDefault = true;
base.OnDrawNode(e);
if (base.ShowLines && base.ImageList != null && e.Node.ImageIndex == NOIMAGE
// exclude root nodes, if root lines are disabled
//&& (base.ShowRootLines || e.Node.Level > 0))
)
{
// Using lines & images, but this node has none: fill up missing treelines
// Image size
int imgW = base.ImageList.ImageSize.Width;
int imgH = base.ImageList.ImageSize.Height;
// Image center
int xPos = e.Node.Bounds.Left - SPACE_IL - imgW / 2;
int yPos = (e.Node.Bounds.Top + e.Node.Bounds.Bottom) / 2;
// Image rect
Rectangle imgRect = new Rectangle(xPos, yPos, 0, 0);
imgRect.Inflate(imgW / 2, imgH / 2);
using (Pen p = new Pen(base.LineColor, 1))
{
p.DashStyle = DashStyle.Dot;
// Account uneven Indent for both lines.
p.DashOffset = base.Indent % 2;
// Horizontal treeline across width of image
// account uneven half of delta ItemHeight & ImageHeight.
int yHor = yPos + ((base.ItemHeight - imgRect.Height) / 2) % 2;
//if (base.ShowRootLines || e.Node.Level > 0)
//{
// e.Graphics.DrawLine(p, imgRect.Left, yHor, imgRect.Right, yHor);
//}
//else
//{
// // for root nodes, if root lines are disabled, start at center
// e.Graphics.DrawLine(p, xPos - (int)p.DashOffset, yHor, imgRect.Right, yHor);
//}
e.Graphics.DrawLine(p,
(base.ShowRootLines || e.Node.Level > 0) ? imgRect.Left : xPos - (int)p.DashOffset,
yHor, imgRect.Right, yHor);
if (!base.CheckBoxes && e.Node.IsExpanded)
{
// Vertical treeline , offspring from NodeImage center to e.Node.Bounds.Bottom
// yStartPos: account uneven Indent and uneven half of delta ItemHeight & ImageHeight
int yVer = yHor + (int)p.DashOffset;
e.Graphics.DrawLine(p, xPos, yVer, xPos, e.Node.Bounds.Bottom);
}
}
}
}
protected override void OnAfterCollapse(TreeViewEventArgs e)
{
base.OnAfterCollapse(e);
if (!base.CheckBoxes && base.ImageList != null && e.Node.ImageIndex == NOIMAGE)
{
// DrawNode event not raised: redraw node with collapsed treeline
base.Invalidate(e.Node.Bounds);
}
}
}
This will give you a TreeView that looks like:
Here my master node (Node[0]
) is the one without a specified Image
and is what you require for your File1
/File2
nodes.
I hope this helps.
Upvotes: 2
Reputation: 4340
Currently you created an images list with only one image (at index 0)
the line treeView1.ImageList = imageList;
links that list to the treeview
the line node2.ImageIndex = 100;
links the image at index 100 (that doesn't exist) on that list to be displayed
you have only one image in the list, that means you have an image only at index 0.
so try that:
node2.ImageIndex = 0;
node2.SelectedImageIndex = 0;
Upvotes: 1