我想让NodeView显示一些分层数据,如下所示:
Father Mother
====== ======
Jon Ann
+Sons
+--Jon 20
+--Dave 10
+Daughters
+--Ann
Ron Mary
Paul Eve
+Sons
+--Bob 4
如果他们是空的,不应该显示“儿子”和“女儿”。
我创建了三个商务类:父母,儿子和女儿,我正在创建TreeNode子类来显示它们。
我使用Monodevelop设计器设计了一个Window,并使用代码重新创建了nodeView。 nodeview根本不显示任何内容,我想知道原因。这是代码,在一个文件中,所以任何人都可以测试它:
using System;
using Gtk;
using System.Collections.Generic;
using System.Linq;
namespace Family.Model
{
public class Son {
public string Name {get;set;}
public string Age {get;set;}
public Son(string n,string a) {
Name=n;Age=a;
}
}
public class Parents
{
public string Father {get;set;}
public string Mother {get;set;}
public List<string> Daughters {get;set;}
public Dictionary<string,Son> Sons {get;set;}
public Parents() {
Daughters=new List<string>();
Sons=new Dictionary<string, Son>();
}
}
}
namespace Family.View
{
using Family.Model;
[TreeNode (ListOnly=false)]
public class ParentsNode:TreeNode
{
private Parents parents;
public ParentsNode (Parents p):base()
{
this.parents=p;
DaughtersRoot rootd=new DaughtersRoot();
SonsRoot roots=new SonsRoot();
if (p.Sons.Count>0) {
this.AddChild (roots);
p.Sons.Values.ToList ().ForEach (x=>roots.AddChild(new SonNode(x)));
}
if (p.Daughters.Count>0) {
this.AddChild (rootd);
p.Daughters.ForEach (x=>rootd.AddChild(new DaughterNode(x)));
}
OnChanged ();
}
[Gtk.TreeNodeValue(Column=0) ]
public string Father {
get { return parents.Father;}
set { parents.Father=value;OnChanged ();}
}
[Gtk.TreeNodeValue (Column=1)]
public string Mother {
get { return parents.Mother; }
set { parents.Mother=value;OnChanged ();}
}
}
[TreeNode(ListOnly=false)]
public class DaughtersRoot:TreeNode
{
[Gtk.TreeNodeValue(Column=0) ]
public string Label {
get {return "Daughters"; }
}
}
[TreeNode(ListOnly=false)]
public class SonsRoot:TreeNode
{
[Gtk.TreeNodeValue(Column=0) ]
public string Label {
get {return "Sons"; }
}
}
[TreeNode(ListOnly=false)]
public class DaughterNode:TreeNode {
private string mName;
public DaughterNode(string s):base() {
this.Name=s;
}
[Gtk.TreeNodeValue(Column=0) ]
public string Name {
get {return mName;}
set {mName=value;OnChanged ();}
}
}
[TreeNode(ListOnly=false)]
public class SonNode:TreeNode {
private Son son;
public SonNode(Son s):base() {
this.son=s;
OnChanged ();
}
[Gtk.TreeNodeValue(Column=0)]
public string Name {
get { return this.son.Name; }
set {son.Name=value;OnChanged ();}
}
[Gtk.TreeNodeValue(Column=1)]
public string Age {
get { return this.son.Age; }
set {son.Age=value;OnChanged ();}
}
}
public class MainWindow: Gtk.Window
{
private global::Gtk.ScrolledWindow GtkScrolledWindow;
private global::Gtk.NodeView treeFamily;
private NodeStore storeParents=new NodeStore(typeof(ParentsNode));
protected virtual void Build ()
{
global::Stetic.Gui.Initialize (this);
// Widget MainWindow
this.Name = "MainWindow";
this.Title = global::Mono.Unix.Catalog.GetString ("MainWindow");
this.WindowPosition = ((global::Gtk.WindowPosition)(4));
this.GtkScrolledWindow = new global::Gtk.ScrolledWindow ();
this.GtkScrolledWindow.Name = "GtkScrolledWindow";
this.GtkScrolledWindow.ShadowType = ((global::Gtk.ShadowType)(1));
this.treeFamily = new global::Gtk.NodeView ();
this.treeFamily.CanFocus = true;
this.treeFamily.Name = "treeFamily";
this.GtkScrolledWindow.Add (this.treeFamily);
this.Add (this.GtkScrolledWindow);
if ((this.Child != null)) {
this.Child.ShowAll ();
}
this.DefaultWidth = 400;
this.DefaultHeight = 300;
this.Show ();
this.DeleteEvent += new global::Gtk.DeleteEventHandler (this.OnDeleteEvent);
}
public MainWindow (): base (Gtk.WindowType.Toplevel) {
Build ();
Parents p=new Parents();
p.Father="Bob";
p.Mother="Mary";
storeParents.AddNode (new ParentsNode (p));
p=new Parents();
p.Father="Ron";
p.Mother="Ann";
p.Sons.Add ("David",new Son("David","20"));
p.Sons.Add ("Matt",new Son("Matt","10"));
p.Daughters.Add ("Elaine");
p.Daughters.Add ("Kate");
storeParents.AddNode (new ParentsNode(p));
this.treeFamily=new NodeView(storeParents);
Gtk.TreeViewColumn fatherColumn = new Gtk.TreeViewColumn
("Father",new CellRendererText(),"text",0);
Gtk.TreeViewColumn motherColumn = new Gtk.TreeViewColumn
("Mother",new CellRendererText(),"text",1);
treeFamily.AppendColumn (fatherColumn);
treeFamily.AppendColumn (motherColumn);
treeFamily.ShowAll ();
}
protected void OnDeleteEvent (object sender, DeleteEventArgs a) {
Application.Quit ();
a.RetVal = true;
}
}
class MainClass
{
public static void Main (string[] args) {
Application.Init ();
MainWindow win = new MainWindow ();
win.Show ();
Application.Run ();
}
}
}
答案 0 :(得分:1)
Gtk模型绑定与其他工具包完全不同。话虽这么说,这是你需要知道的开始:
有几种类型的“控件”或小部件,因为它们在GTK中被调用,可以显示矩阵/列表数据:
现在,AFAIC,NodeView只存在于GTK#中,即.Net绑定。 TreeView在所有其他绑定中都可用,并且是GTK + Core的一部分。不同的是,NodeView更容易使用但更有限。
如果您只需显示列表数据,即没有分层数据(您似乎需要),您将需要使用NodeView
如果您需要显示分层数据,那么您将使用TreeView。
无论您使用哪种,您还必须在该小部件中设置您需要的内容,例如您的列。 GTK中的NodeView / TreeView单元格与其他基本工具包之间的区别在于NodeView列可以在其单元格内显示其他小部件而不仅仅是文本,因此您可以使用一个列具有显示进度条的单元格,或者一个复选框。您在这些单元格中使用的小部件称为CellRenderers,还有CellRendererText,CellRenderToggle等。
现在,这些控件通过“商店”“绑定”到数据,例如:
您将使用哪一个取决于您的需求以及您要使用的小部件类型,因此如果您只需要显示简单数据,请使用NodeStore,如果您需要显示分层数据,请使用TreeStore。这些数据存储的一个强大功能是,您不仅可以在其中存储NodeView / TreeView小部件上显示的数据,还可以存储不一定需要显示的任何其他数据,甚至可以存储对象,例如,您可以有一个包含4列的商店,其中3列显示在小部件上,第4列保留完整对象的实例。
在this链接中,我提到的每个案例的样本都可以尝试。我认为您应该使用“树”模型来完成您想要的而不是“节点”。
GTK是一个功能强大的工具包,但有时很难理解它是如何工作的。我希望这个介绍适合你。