treenode - treeview

  • Thread starter Thread starter Dean L. Howen
  • Start date Start date
D

Dean L. Howen

Hi,

I want to add some attributes to TreeNode, so I create a new class MyNode
that inheritance from System.Windows.Forms.TreeNode,
I want to TreeView use MyNode instead of TreeNode, so I can manipulate with
new attributes
How can? Please give me some ideas,
Thanks.

Because the TreeNode doesn't have Value Property which contents value behind
the diplayed text in TreeView
 
The TreeNode has a propery called Tag which is of type object. You can use
this property to store a single value or a whole object such as your MyNode
class.
 
I agree with RH. Use the tag object to store any object you want. You can
inherit from treeview and treenode, but then you need to override a bunch of
stuff to get the strong typing you desire which would start to get messy.
 
Below is my subclassed TreeNode with TreeView. On your windows you will add
the exTreeView and then add exTreeNode to the view. Now if you are like me
and need to display this new data then you will need to override the windows
painting with "unsafe protected override void WndProc(ref Message m)". I
think that's it but I might have left something out, this was pulled for
working code but it's rather large to post the whole thing here.

Hope this helps,
John

////////////////////////////
// makding a tree view
///////////////////////////
exTreeView tvMsg = new exTreeView()
.... put it some place

////////////////////////////
// Adding a node
////////////////////////////
exTreeNode node = new exTreeNode();
Node.Bmp = new Bitmap(128, 16, PixelFormat.Format1bppIndexed);
this.tvMsg.Nodes[idx].Nodes.Add(msgNode);

/////////////////////////
// Tree node stuff
////////////////////////
namespace TreeStuff
{
[Serializable()]
public class exTreeNode : TreeNode
{
private Bitmap bmp;
public Bitmap Bmp
{
get { return this.bmp; }
set { this.bmp = value; }
}
public exTreeNode() : base()
{ }
}

public class exTreeView : TreeView
{
public exTreeView() : base()
{
}

protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.Black, e.ClipRectangle);
}

}
}

////////////////////////////////////
// painting the node
///////////////////////////////////
unsafe protected override void WndProc(ref Message m)
{
IntPtr inp;
NMCUSTOMDRAW *lp2;
NMHDR *lp;

inp=IntPtr.Zero ;

//Handle Notify message
if (m.Msg ==WM_NOTIFY)
{
lp=null;
lp=(NMHDR*)m.LParam.ToPointer ();
{
//Message is NM_CUSTOMDRAW
if (lp->code ==NM_CUSTOMDRAW)
{
lp2=(NMCUSTOMDRAW*)m.LParam.ToPointer ();

//It is a message Paint Item. Here we shall do some painting
if (lp2->dwDrawStage==CDDS_ITEMPREPAINT) //CDDS_ITEMPREPAINT
{
base.WndProc(ref m);
TreeViewPaint (ref m);
m.Result =(IntPtr)(0);
return;
}
else
{
//We shall return this value to get messages about item painting
m.Result =(IntPtr)CDRF_NOTIFYSUBITEMDRAW; ;
}

}
}
}
base.WndProc(ref m);
}

// This function paints additional info.
unsafe public void TreeViewPaint(ref Message m)
{
NMCUSTOMDRAW *lp2;
System.Drawing.Graphics g;
exTreeNode node;

lp2=(NMCUSTOMDRAW*)m.LParam.ToPointer ();

//Paint only this control items
//Now we have only one treeview so this code is commented
//if ((uint)this.Handle !=lp2->hdr.hwndFrom )
//{return;}

//Get graphic device
g=System.Drawing.Graphics.FromHwnd (this.tvMsg.Handle );


//Get node which we are going to paint
node = (exTreeNode)this.tvMsg.GetNodeAt((int)lp2->x1+1,(int)lp2->y1+1);

long x1=lp2->x1+node.Bounds.X +node.Bounds.Width +5;
long y1=lp2->y1;
if(node.Bmp != null)
{
g.DrawImage(node.Bmp, x1, y1, node.Bmp.Width, node.Bmp.Height);
}

return;
}
 
I agree with RH solution. It's simpler than John'one ( it's more complex,
have to do many modify, but it's great. ).

Thank you for all your help!
 
Hi,
According your solution, if I want to get the new attribute value, I have
more work to do, right?

Anyway, thank you to show me many solution.

-------------



John J. Hughes II said:
Below is my subclassed TreeNode with TreeView. On your windows you will add
the exTreeView and then add exTreeNode to the view. Now if you are like me
and need to display this new data then you will need to override the windows
painting with "unsafe protected override void WndProc(ref Message m)". I
think that's it but I might have left something out, this was pulled for
working code but it's rather large to post the whole thing here.

Hope this helps,
John

////////////////////////////
// makding a tree view
///////////////////////////
exTreeView tvMsg = new exTreeView()
... put it some place

////////////////////////////
// Adding a node
////////////////////////////
exTreeNode node = new exTreeNode();
Node.Bmp = new Bitmap(128, 16, PixelFormat.Format1bppIndexed);
this.tvMsg.Nodes[idx].Nodes.Add(msgNode);

/////////////////////////
// Tree node stuff
////////////////////////
namespace TreeStuff
{
[Serializable()]
public class exTreeNode : TreeNode
{
private Bitmap bmp;
public Bitmap Bmp
{
get { return this.bmp; }
set { this.bmp = value; }
}
public exTreeNode() : base()
{ }
}

public class exTreeView : TreeView
{
public exTreeView() : base()
{
}

protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.Black, e.ClipRectangle);
}

}
}

////////////////////////////////////
// painting the node
///////////////////////////////////
unsafe protected override void WndProc(ref Message m)
{
IntPtr inp;
NMCUSTOMDRAW *lp2;
NMHDR *lp;

inp=IntPtr.Zero ;

//Handle Notify message
if (m.Msg ==WM_NOTIFY)
{
lp=null;
lp=(NMHDR*)m.LParam.ToPointer ();
{
//Message is NM_CUSTOMDRAW
if (lp->code ==NM_CUSTOMDRAW)
{
lp2=(NMCUSTOMDRAW*)m.LParam.ToPointer ();

//It is a message Paint Item. Here we shall do some painting
if (lp2->dwDrawStage==CDDS_ITEMPREPAINT) //CDDS_ITEMPREPAINT
{
base.WndProc(ref m);
TreeViewPaint (ref m);
m.Result =(IntPtr)(0);
return;
}
else
{
//We shall return this value to get messages about item painting
m.Result =(IntPtr)CDRF_NOTIFYSUBITEMDRAW; ;
}

}
}
}
base.WndProc(ref m);
}

// This function paints additional info.
unsafe public void TreeViewPaint(ref Message m)
{
NMCUSTOMDRAW *lp2;
System.Drawing.Graphics g;
exTreeNode node;

lp2=(NMCUSTOMDRAW*)m.LParam.ToPointer ();

//Paint only this control items
//Now we have only one treeview so this code is commented
//if ((uint)this.Handle !=lp2->hdr.hwndFrom )
//{return;}

//Get graphic device
g=System.Drawing.Graphics.FromHwnd (this.tvMsg.Handle );


//Get node which we are going to paint
node = (exTreeNode)this.tvMsg.GetNodeAt((int)lp2->x1+1,(int)lp2->y1+1);

long x1=lp2->x1+node.Bounds.X +node.Bounds.Width +5;
long y1=lp2->y1;
if(node.Bmp != null)
{
g.DrawImage(node.Bmp, x1, y1, node.Bmp.Width, node.Bmp.Height);
}

return;
}
 
You can add any value you want to the exTreeNode and use it from code with
only a few changes. The problem is if you want to display the value in the
tree itself then you have to handle that condition. If you don't wish to
display the data in the tree then all you reall need to do is make the
exTreeNode and use it instead of TreeNode.

Regards,
John

Dean L. Howen said:
Hi,
According your solution, if I want to get the new attribute value, I have
more work to do, right?

Anyway, thank you to show me many solution.

-------------



John J. Hughes II said:
Below is my subclassed TreeNode with TreeView. On your windows you will add
the exTreeView and then add exTreeNode to the view. Now if you are like me
and need to display this new data then you will need to override the windows
painting with "unsafe protected override void WndProc(ref Message m)". I
think that's it but I might have left something out, this was pulled for
working code but it's rather large to post the whole thing here.

Hope this helps,
John

////////////////////////////
// makding a tree view
///////////////////////////
exTreeView tvMsg = new exTreeView()
... put it some place

////////////////////////////
// Adding a node
////////////////////////////
exTreeNode node = new exTreeNode();
Node.Bmp = new Bitmap(128, 16, PixelFormat.Format1bppIndexed);
this.tvMsg.Nodes[idx].Nodes.Add(msgNode);

/////////////////////////
// Tree node stuff
////////////////////////
namespace TreeStuff
{
[Serializable()]
public class exTreeNode : TreeNode
{
private Bitmap bmp;
public Bitmap Bmp
{
get { return this.bmp; }
set { this.bmp = value; }
}
public exTreeNode() : base()
{ }
}

public class exTreeView : TreeView
{
public exTreeView() : base()
{
}

protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.Black, e.ClipRectangle);
}

}
}

////////////////////////////////////
// painting the node
///////////////////////////////////
unsafe protected override void WndProc(ref Message m)
{
IntPtr inp;
NMCUSTOMDRAW *lp2;
NMHDR *lp;

inp=IntPtr.Zero ;

//Handle Notify message
if (m.Msg ==WM_NOTIFY)
{
lp=null;
lp=(NMHDR*)m.LParam.ToPointer ();
{
//Message is NM_CUSTOMDRAW
if (lp->code ==NM_CUSTOMDRAW)
{
lp2=(NMCUSTOMDRAW*)m.LParam.ToPointer ();

//It is a message Paint Item. Here we shall do some painting
if (lp2->dwDrawStage==CDDS_ITEMPREPAINT) //CDDS_ITEMPREPAINT
{
base.WndProc(ref m);
TreeViewPaint (ref m);
m.Result =(IntPtr)(0);
return;
}
else
{
//We shall return this value to get messages about item painting
m.Result =(IntPtr)CDRF_NOTIFYSUBITEMDRAW; ;
}

}
}
}
base.WndProc(ref m);
}

// This function paints additional info.
unsafe public void TreeViewPaint(ref Message m)
{
NMCUSTOMDRAW *lp2;
System.Drawing.Graphics g;
exTreeNode node;

lp2=(NMCUSTOMDRAW*)m.LParam.ToPointer ();

//Paint only this control items
//Now we have only one treeview so this code is commented
//if ((uint)this.Handle !=lp2->hdr.hwndFrom )
//{return;}

//Get graphic device
g=System.Drawing.Graphics.FromHwnd (this.tvMsg.Handle );


//Get node which we are going to paint
node = (exTreeNode)this.tvMsg.GetNodeAt((int)lp2->x1+1,(int)lp2->y1+1);

long x1=lp2->x1+node.Bounds.X +node.Bounds.Width +5;
long y1=lp2->y1;
if(node.Bmp != null)
{
g.DrawImage(node.Bmp, x1, y1, node.Bmp.Width, node.Bmp.Height);
}

return;
}
 
Back
Top