[Gtk-sharp-list] System.Reflection & Managed TreeView Don't Mix

Jonathan Pryor jonpryor@vt.edu
28 Jun 2003 00:23:46 -0400

Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Here's an interesting bug for you.  I'll throw it in Bugzilla if
appropriate.  I find it to be a major bug.

Programs that make use of reflection (e.g. Type Reflector) don't work
correctly with the Gtk# TreeView widget (or maybe TreeStore, I haven't
really narrowed it down much).

See the attached file.  It's a variation of the Gtk#
ManagedTreeViewDemo.  The difference is that, just for "fun", it loads
corlib.dll and prints out the name of all types in corlib.  Nothing
particularly fancy.

What's interesting is the resulting behavior.  If you run the attached
demo without using reflection:


You get the same results as the normal ManagedTreeViewDemo program -- a
table with foos, bars, bazs, etc.

However, if you use reflection:

	./ManagedTreeViewDemo.exe --use-reflection

Then I get varying behavior.  Typically, the TreeView appears to be
empty.  I can select rows, so I know the TreeView *thinks* it contains
data, but nothing is shown to me.  Another time, the first column was
empty, but the second column still had data.  It's variable.

Furthermore, it appears to be somewhat dependent upon how many types are
in the assembly.  The whole reason I came across this issue was because
I migrated Type Reflector to use the managed TreeView code, but the
TreeView was empty when using type-reflector.exe as input (~80 types). 
However, if I just used an assembly with the test types (~10 types), the
interface worked correctly.


 - Jon

Content-Disposition: attachment; filename=ManagedTreeViewDemo.cs
Content-Type: text/plain; name=ManagedTreeViewDemo.cs; charset=UTF-8
Content-Transfer-Encoding: 7bit

// ManagedTreeViewDemo.cs - Another TreeView demo
// Author: Rachel Hestilow <hestilow@ximian.com>
// (c) 2003 Rachel Hestilow

namespace GtkSamples {
	using System;
	using System.Drawing;
	using System.Runtime.InteropServices;
  using System.Reflection;

	using Gtk;
	using GtkSharp;

	public class TreeViewDemo {
		private static ListStore store = null;
		private class Pair {
			public string a, b;
			public Pair (string a, string b) {
				this.a = a;
				this.b = b;

		private static void PopulateStore ()
			store = new ListStore (typeof (Pair));
			string[] combs = {"foo", "bar", "baz", "quux"};
			foreach (string a in combs) {
				foreach (string b in combs) {
					store.AppendValues (new Pair (a, b));

		private static void CellDataA (Gtk.TreeViewColumn tree_column, Gtk.CellRenderer cell, Gtk.TreeModel tree_model, Gtk.TreeIter iter)
			Pair val = (Pair) store.GetValue (iter, 0);
			((CellRendererText) cell).Text = val.a;
		private static void CellDataB (Gtk.TreeViewColumn tree_column, Gtk.CellRenderer cell, Gtk.TreeModel tree_model, Gtk.TreeIter iter)
			Pair val = (Pair) store.GetValue (iter, 0);
			((CellRendererText) cell).Text = val.b;
		static extern void gtk_init (ref int argc, ref String[] argv);

		public static void Main (string[] args)
			Application.Init ();

			PopulateStore ();

			Window win = new Window ("TreeView demo");
			win.DeleteEvent += new DeleteEventHandler (DeleteCB);
			win.DefaultSize = new Size (320,480);

			ScrolledWindow sw = new ScrolledWindow ();
			win.Add (sw);

			TreeView tv = new TreeView (store);
			tv.HeadersVisible = true;

			tv.AppendColumn ("One", new CellRendererText (), new TreeCellDataFunc (CellDataA));
			tv.AppendColumn ("Two", new CellRendererText (), new TreeCellDataFunc (CellDataB));

			if (args.Length > 0 && args[0] == "--use-reflection")
				UseReflection ();

			sw.Add (tv);
			win.ShowAll ();

			Application.Run ();

		private static void UseReflection ()
			Assembly a = Assembly.Load ("corlib.dll");
			foreach (Type t in a.GetTypes())
				Console.WriteLine ("found type: {0}", t);

		private static void DeleteCB (System.Object o, DeleteEventArgs args)
			Application.Quit ();