【gtk#】关于treeview数据绑定,选择及添加删除节点数据的备忘录

【前言】

【mono的gtk#有无法识别中文路径的bug,假如你用xamarin studio开发gtk#工程的话,我建议你将工程放到完全英文的路径下面,免却很多麻烦】

最近在搞gtk#,mono下面的一个桌面ui框架,是对gtk+的c#版本,为什么我不停去搞不同的技术呢?只因为我在找一个解决方案。

多余的不说了,

下面上代码。


【正文】


treeview的用法。

gtk#里面没有listview,没有datagridview等等控件,但是有一个近乎万能的treeview。


treeview数据的绑定:

		//绑定列及单元格

		listConn.AppendColumn ("数据类型", new CellRendererPixbuf (), "pixbuf", 0);	

		listConn.AppendColumn ("编号", new CellRendererText (), "text", 1);

		listConn.AppendColumn ("连接名称", new CellRendererText (), "text", 2);

		_connListStore = new ListStore (typeof(Gdk.Pixbuf),typeof(int),typeof(string));



		//--获取列表

		CodeGen.DAL.ConnectionDAL cdal = new CodeGen.DAL.ConnectionDAL ();

		List<ConnectionModel> clist=  cdal.getList ();



		foreach(ConnectionModel ctmp in clist){

			Gdk.Pixbuf pbuf = new Gdk.Pixbuf ("resources/database_icon.png", 24, 24);



			_connListStore.AppendValues (pbuf,ctmp.id,  ctmp.title);

		}



		listConn.Model = _connListStore;

		//不要让我看见表头

		listConn.HeadersVisible = false;

		//隐藏“编号”列

		listConn.Columns [1].Visible = false;

下面是讲解:

gtk#里面的treeview控件是根据mvc原则来确定的。则:使用treeview的时候必须指定数据源,而官方的数据源就两种 liststore及treestore---比起wpf逊色多了,wpf什么都可以绑。

liststore用于显示列表式的数据,而treestore则显示下面有节点的数据。

_connListStore = new ListStore (typeof(Gdk.Pixbuf),typeof(int),typeof(string));

这就是数据源的定义方式,里面的typeofxxx是对应于你将放进去的数据的格式,譬如上面定义了三个参数,一个是图片类型,一个是整数类型,一个是字符串类型,下面如何给数据源添加数据呢?

		foreach(ConnectionModel ctmp in clist){

			Gdk.Pixbuf pbuf = new Gdk.Pixbuf ("resources/database_icon.png", 24, 24);



			_connListStore.AppendValues (pbuf,ctmp.id,  ctmp.title);

		}

没错,就是用上面这种方式了,这种方式看上去有点古老。

listConn.Model = _connListStore;

好了绑定了,但是这时候运行你是不会看到任何东西的,因为你只是绑定了数据,没有指定数据的列对应何种参数:

listConn.AppendColumn ("数据类型", new CellRendererPixbuf (), "pixbuf", 0);

ok,基本完成,每一列都定义好了,假如不希望看到表头的话,请用 headersvisible=false来设定。


【treeview的treestore及树形结构】

		_treeStore_Db = new TreeStore (typeof(Gdk.Pixbuf), typeof(string));

		tree_dbDetail.HeadersVisible = false;

		tree_dbDetail.AppendColumn ("logo", new CellRendererPixbuf (), "pixbuf", 0);	

		tree_dbDetail.AppendColumn ("名称", new CellRendererText (), "text", 1);



		_treeIter_tables= _treeStore_Db.AppendValues (new Gdk.Pixbuf ("resources/table3.png", 24, 24), "数据表");

		_treeIter_views = _treeStore_Db.AppendValues (new Gdk.Pixbuf ("resources/view_icon.png", 24, 24), "视图");

		_treeIter_procs = _treeStore_Db.AppendValues (new Gdk.Pixbuf ("resources/database_active.png", 24, 24), "存储过程");



		tree_dbDetail.Model = _treeStore_Db;

treestore的绑定与liststore大同小异,不过请注意,给treestore添加相关参数后会返回当前节点,不过假如你想自由自在地控制,你可以用:

_treeStore_Db.IterChildren(out childNode)

获得根目录下面的第一个子节点,还有另一种用法

_treeStore_Db.IterChildren (out childNode,_treeIter_views);
这种用法表示_treeIter_views下面的第一个节点。

或者这样得到下一个节点:

_treeStore_Db.IterNext (out childNode,_treeIter_views);
或者:

_treeStore_Db.IterNext (out childNode);

这两种用法与上面的雷同。


【如何添加选中事件,如何清楚下属节点,如何添加下属节点?】

添加选中事件:

this.listConn.RowActivated += new global::Gtk.RowActivatedHandler (this.OnRowActivated);

然后编写相关事件:

	/// <summary>

	/// 当选择某个行时的操作

	/// </summary>

	/// <param name="o">O.</param>

	/// <param name="args">Arguments.</param>

	protected void OnRowActivated (object o, RowActivatedArgs args)

	{/*

		MessageDialog mydialog = new MessageDialog (this, DialogFlags.Modal, MessageType.Info,ButtonsType.Ok,"您好吗?");







		 ResponseType res1= (ResponseType)mydialog.Run ();

		if (res1 == ResponseType.Ok) {

			mydialog.Destroy ();

		}

		*/

		TreeView view = (TreeView)o;

		TreeIter iter;

		view.Model.GetIter (out iter, args.Path);

		int theRecordID= (int)view.Model.GetValue (iter, 1);

		ConnectionDAL cdal = new ConnectionDAL ();

		ConnectionModel cmodel=  cdal.getRecord (theRecordID);

		MSSQLProvider mspro = new MSSQLProvider (cmodel.serverip, cmodel.account, cmodel.pwd, cmodel.database);

		List<string> tableNames=  mspro.getTableNames ();

		List<string> procNames = mspro.getProcNames ();

		/*请空每一个节点下面的子节点*/

		TreeIter childNode;

		while(_treeStore_Db.IterChildren (out childNode, _treeIter_tables)==true){

			_treeStore_Db.Remove (ref childNode);

		}

		while(_treeStore_Db.IterChildren (out childNode, _treeIter_procs)==true){

			_treeStore_Db.Remove (ref childNode);

		}



		/*绑定*/

		foreach(string tableName1 in tableNames){

			_treeStore_Db.AppendValues (_treeIter_tables, new Gdk.Pixbuf ("resources/table163.png", 18, 18), tableName1);

			}



		foreach(string procName1 in procNames){

			_treeStore_Db.AppendValues (_treeIter_procs, new Gdk.Pixbuf ("resources/database.png", 18, 18), procName1);

		}

		/*树形结构默认是闭合的,将三个节点全都打开。*/

		tree_dbDetail.ExpandToPath (_treeStore_Db.GetPath (_treeIter_tables));

		tree_dbDetail.ExpandToPath (_treeStore_Db.GetPath (_treeIter_procs));

		tree_dbDetail.ExpandToPath (_treeStore_Db.GetPath (_treeIter_views));







	}

有了上面的知识以后你可能会比较明白了:

		TreeView view = (TreeView)o;

		TreeIter iter;

		view.Model.GetIter (out iter, args.Path);

首先,获得当前选中的节点,然后,将相关下属节点清楚干净再添加:


		/*请空每一个节点下面的子节点*/

		TreeIter childNode;

		while(_treeStore_Db.IterChildren (out childNode, _treeIter_tables)==true){

			_treeStore_Db.Remove (ref childNode);

		}

		while(_treeStore_Db.IterChildren (out childNode, _treeIter_procs)==true){

			_treeStore_Db.Remove (ref childNode);

		}



		/*绑定*/

		foreach(string tableName1 in tableNames){

			_treeStore_Db.AppendValues (_treeIter_tables, new Gdk.Pixbuf ("resources/table163.png", 18, 18), tableName1);

			}



		foreach(string procName1 in procNames){

			_treeStore_Db.AppendValues (_treeIter_procs, new Gdk.Pixbuf ("resources/database.png", 18, 18), procName1);

		}

中间那一段代码是代码生成器相关代码,意思是获得相关数据库的所有表名,存储过程名称等等。

附带一张半成品:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值