您的位置:首页 > 编程语言 > C#

C# 实现 treeView 控件 拖拽效果

2013-04-28 00:05 381 查看

引言

  近日,在工作中遇到 treeView控件 要只是 展开或收起节点实在是太单调了,如果能像window那样的拖动效果就好了,于是乎就开始折腾如何让他能实现拖拽的效果......

正文

  都说万事开头难, (就像我现在思考怎么写...#^.^#), 一开始我就在表的设计上难住了,在数据库中怎样去保存 动态 拖拽的 树节点呢???

  思考中...........................

  继续思考.......................

  在不看我下面的实现方法之前,有兴趣可以思考一下哦。

  您有想法了吗?

  我的实现方式是:设计了两个字段就OK了,一个NodeId,parentId,为了能够看得出效果,我附加了一个 Title 树节点的标题,

  NodeId不用讲( PRIMARY KEY AUTOINCREMENT) parentId用来保存 拖动节点 所在的 父级节点NodeId 即可,似乎有些绕,举例:比如不管我怎么拖动节点a,节点a肯定会位于某个节点(就叫节点b 吧)之下,只要用节点a 的parentId保存 节点b 的NodeId即可。

数据库

[b]全部代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using FileManager;

namespace DropTree
{
public partial class Form1 : Form
{

string ComPath = System.IO.Directory.GetCurrentDirectory() + "\\Test.db";
public Form1()
{
InitializeComponent();
this.Load+=new EventHandler(Form1_Load);
//如果控件允许拖放操作,则为 true;否则为 false。默认为 false。
treeView1.AllowDrop = true;
treeView1.ItemDrag += new ItemDragEventHandler(treeView1_ItemDrag);
treeView1.DragEnter += new DragEventHandler(treeView1_DragEnter);
treeView1.DragDrop += new DragEventHandler(treeView1_DragDrop);
}

private void Form1_Load(object sender, EventArgs e)
{
IniTable();
IniTreeView();
//展开所有节点
this.treeView1.ExpandAll();
treeView1.SelectedNode = null;
}
//  在拖拽时要注意的是:1.目标节点不能为空。2.目标节点不能被拖拽节点本身。3.目标节点不能是被拖拽节点的子节点。
//1.ItemDrag事件(当用户开始拖动节点时发生。)2.DragEnter事件(在将对象拖入控件的边界时发生。)3.DragDrop事件(在完成拖放操作时发生。)

#region   初始化数据库
public void IniTable()
{
try
{
MessageBox.Show(ComPath);
//如果不存在数据库文件,则创建该数据库文件
if (!System.IO.File.Exists(ComPath))
{
SQLiteDBHelper.CreateDB(ComPath);
SQLiteDBHelper db = new SQLiteDBHelper(ComPath);
string sql = "CREATE TABLE TTree(NodeId integer NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,Title  varchar(50),parentId varchar(20),CreateTime datetime,UpdateTime Date )   ";
//sql += "  CREATE TABLE TContent (NodeId integer NOT NULL,Title varchar(50),Type varchar(50),Size varchar(50),Time time,CreateTime datetime,UpdateTime datetime, Content blob)";
db.ExecuteNonQuery(sql, null);
}

}
catch (Exception)
{

throw;
}

}

#endregion

#region 加载树
public void IniTreeView()
{
treeView1.Nodes.Clear();
//添加根节点

string strSQL;
strSQL = "select * from TTree where parentId = 0";
SQLiteDBHelper db = new SQLiteDBHelper(ComPath);
DataTable dt = db.ExecuteDataTable(strSQL,null);

if (dt.Rows.Count > 0)
{
DataView tmpDV = new DataView(dt);
if (tmpDV.Count > 0)
{
foreach (DataRowView myView in tmpDV)
{
string strTreeNode = myView["Title"].ToString().Trim();
TreeNode tmp = new TreeNode(strTreeNode, 0, 1);
tmp.Tag = myView["NodeId"];
treeView1.Nodes.Add(tmp);
treeView1.SelectedNode = tmp;
ChildTreeView(tmp, myView);  //递归填充树子节点
}
}
}
}

private void ChildTreeView(TreeNode ParentNode, DataRowView ParentRow)
{

string strNode;
string sParentNode = ParentRow["NodeId"].ToString().Trim();
SQLiteDBHelper db = new SQLiteDBHelper(ComPath);
string strSQL = "select * from TTree where parentId=" + Convert.ToInt32(ParentRow["NodeId"]);
DataTable dtTree = db.ExecuteDataTable(strSQL,null);
if (dtTree.Rows.Count > 0)
{
DataView tmpDV = new DataView(dtTree);
foreach (DataRowView myRow in tmpDV)
{
strNode = myRow["Title"].ToString().Trim();
TreeNode myNode = new TreeNode(strNode, 0, 1);
myNode.StateImageIndex = 1;
myNode.Tag = myRow["NodeId"];
ParentNode.Nodes.Add(myNode);
ChildTreeView(myNode, myRow);

}
}
}
#endregion

#region  树节点拖动效果
Point Position = new Point(0, 0);
//当用户开始拖动节点时发生
private void treeView1_ItemDrag(object sender, ItemDragEventArgs e)
{
DoDragDrop(e.Item, DragDropEffects.Move);
}

//在将对象拖入控件的边界时发生
private void treeView1_DragEnter(object sender, DragEventArgs e)
{
//判断拖动的是否为树节点
if (e.Data.GetDataPresent(typeof(TreeNode)))
e.Effect = DragDropEffects.Move;
else
e.Effect = DragDropEffects.None;
}

//在完成拖放操作时发生
private void treeView1_DragDrop(object sender, DragEventArgs e)
{
string Moveid = "", Dropid = "";

TreeNode myNode = null;
if (e.Data.GetDataPresent(typeof(TreeNode)))
{
//获得移动节点
myNode = (TreeNode)(e.Data.GetData(typeof(TreeNode)));
//获得移动节点的NodeId
Moveid = (string)myNode.Tag.ToString();

}
else
{
MessageBox.Show("error");
}

//将树节点的位置计算成工作区坐标。
Position.X = e.X;
Position.Y = e.Y;
Position = treeView1.PointToClient(Position);

//检索目标节点
TreeNode DropNode = this.treeView1.GetNodeAt(Position);
// 1.目标节点不是空。2.目标节点不是被拖拽接点的子节点。3.目标节点不是被拖拽节点本身
if (DropNode != null && DropNode.Parent != myNode && DropNode != myNode)
{
//临时节点
TreeNode tempNode = myNode;
// 将被拖拽节点从原来位置删除。
myNode.Remove();
// 在目标节点下增加被拖拽节点
DropNode.Nodes.Add(tempNode);
//目标节点的NodeId值
Dropid = (string)DropNode.Tag.ToString();

//数据库中更新移动节点的parentID
string strSQL;
strSQL = " update TTree set parentId =" + Dropid + "   where  NodeId = " + Moveid + "  ";
SQLiteDBHelper db = new SQLiteDBHelper(ComPath);
int i = db.ExecuteNonQuery(strSQL,null);
if (i < 0)
{
MessageBox.Show("请正确拖动文件");
}

}
// 如果目标节点不存在,即拖拽的位置不存在节点,那么就将被拖拽节点放在根节点之下
if (DropNode == null)
{
//parentId = 0  表示根节点
string strSQL;
strSQL = " update TTree set parentId = 0   where  NodeId = " + Moveid + "  ";
SQLiteDBHelper db = new SQLiteDBHelper(ComPath);
int i = db.ExecuteNonQuery(strSQL, null);

TreeNode DragNode = myNode;
myNode.Remove();
treeView1.Nodes.Add(DragNode);
}
}
#endregion

}
}


如有问题或建议,欢迎留言 ~ 博客地址:http://www.cnblogs.com/zqiang/

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: