[Gtk-sharp-list] Heterogeneous Nodes In Gtk.NodeView / Gtk.NodeStore

Christian Hoff christian_hoff at gmx.net
Mon Apr 20 14:56:39 EDT 2009

Slug wrote:
> I have a requirement to have a tree that contains different node types at
> different levels.  I have gotten  this to work using the TreeView /
> TreeStore data structures, but it was so cumbersome to support that I tried
> the NodeView / NodeStore pattern as a test.  So following the example of
> songs provided in the Tutorial
> (http://mono-project.com/GtkSharpNodeViewTutorialExamples ), My requirement
> would be to have tree something like this:
> ARTIST                    SONG
> -----------                     ----------
> 60s ROCK
>   -  Beatles              Yesterday.
> NOT 60s ROCK
>   -  Peter Gabriel      In Your Eyes
>   -  Rush                 Fly By Night
> So I modified the example as follows, and I ran into a few issues/questions
> that I thought I might share:
> 2)    If you put in an abstract node type in the store constructor ( e.g.
> Gtk.NodeStore (typeof (Gtk.TreeNode) )  ) - the
>        whole thing loads, but crashes later when it tries to display the
> tree.
> This was important because I wanted to create a second class 
> 		public class GenreNode : Gtk.TreeNode {		
>                         [Gtk.TreeNodeValue (Column=0)]		
> 			public string Genre {get; set; }
> 		}
> and then change the way the store gets loaded to something like this 
> 		GenreNode t60sRock = new GenreNode() {Genre = "60s Rock" };
> 		store.AddNode( t60sRock );					
>                 t60sRock.AddChild (new MyTreeNode ("The Beatles",
> "Yesterday"));
>                 GenreNode tNot60sRock = new GenreNode() {Genre = "Not 60s
> Rock"};
> 		store.AddNode( tNot60sRock );
>                 tNot60sRock.AddChild (new MyTreeNode ("Peter Gabriel", "In
> Your Eyes"));
>                 tNot60sRock.AddChild (new MyTreeNode ("Rush", "Fly By
> Night"));
> I would hope that it would produce the tree I drew above (which can be
> acheived using the TreeView/TreeStore).  I was hopeful because NodeView
> inherits from TreeView. But instead the approach just crashes too with now
> exception thrown.
> It seems hopeless because we need to pass the node's class type into the
> store's constructor.  Its there some some hidden instantiation going on
> behind the scenes that breaks it?   Why is it necessary to pass the type
> anyway?  Why restrict the all the nodes in a tree to a single type ??  Would
> it be possible to just capture the type of each individual node (
> t60sRock.GetType() ) as it is added and track that inside the NodeStore
> somewhere unseen?
The type needs to be passed in the constructor to calculate the number
of columns and their respective types. Furthermore, we store the
fields/properties having an associated TreeNodeValueAttribute so that we
don't have too look these up every time a value is being requested from
the model.

That's why your approach won't work. NodeStore will look for these
attributes in Gtk.NodeStore and won't find any columns at all. Fixing
this shouldn't be too difficult(just check if the type of the node
passed to AddNode has already been scanned for TreeNodeValueAttributes,
if not, scan the type and cache the accessors somehow), but it would
result in a loss of performance. If you consider to fix that yourself,
you should write a mail to Mike Kestner (mkestner at gmail.com) to ask him
whether we want to fix that in Gtk#.


More information about the Gtk-sharp-list mailing list