老规矩,先说一下我的思路。。。鉴于个人语文水平,这次就用图来说明了
大概的思路就是这个样子,下面就是具体的实现方法(关于数状图的数据绑定可以参考我之前的动态绑定菜单,原理是一样的):
XAML:
<TreeView Name="allFunctions" HorizontalAlignment="Left" Height="250" Margin="501,75,0,0" VerticalAlignment="Top" Width="250" AllowDrop="True" MouseMove="treeView_MouseMove"/>
<TreeView Name="portionFunctions" HorizontalAlignment="Left" Height="250" Margin="33,75,0,0" VerticalAlignment="Top" Width="250" AllowDrop="True" DragDrop.Drop="treeView_OnDrop"/>
CS:
#region 全局变量
/// <summary>
/// 节点数据信息(保存所有节点)
/// </summary>
DataTable dataTable;
/// <summary>
/// 定义一个原点坐标
/// </summary>
Point _lastMouseDown;
/// <summary>
/// 实例化栈
/// </summary>
Stack<DataRow> stack = new Stack<DataRow>();
/// <summary>
/// 父节点
/// </summary>
string FatherNode;
/// <summary>
/// 拖拽的节点信息
/// </summary>
TreeViewItem draggedItem;
#endregion
/// <summary>
/// 鼠标移入事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void treeView_MouseMove(object sender, MouseEventArgs e)
{
try
{
if (e.LeftButton == MouseButtonState.Pressed)
{
//获取鼠标移动的距离
Point currentPosition = e.GetPosition(allFunctions);
//判断鼠标是否移动
if ((Math.Abs(currentPosition.X - _lastMouseDown.X) > 10.0) ||
(Math.Abs(currentPosition.Y - _lastMouseDown.Y) > 10.0))
{
//获取鼠标选中的节点数据
draggedItem = (TreeViewItem)allFunctions.SelectedItem;
if (draggedItem != null)
{
//启动拖放操作
DragDropEffects finalDropEffect = DragDrop.DoDragDrop(allFunctions, allFunctions.SelectedValue,
DragDropEffects.Copy);
}
}
}
}
catch (Exception)
{
}
}
/// <summary>
/// 拖放结束
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void treeView_OnDrop(object sender, DragEventArgs e)
{
Point pos = e.GetPosition(portionFunctions);
HitTestResult result = VisualTreeHelper.HitTest(portionFunctions, pos);
if (result == null)
return;
//目标节点
TreeViewItem treeViews = new TreeViewItem();
//检查是否存在父节点
DataRow treeInfo = dataTable.Select("ID ="+draggedItem.Uid).FirstOrDefault();
CheckElement(treeInfo);
//判断portionFunctions中是否已经存在节点
if (portionFunctions.Items.Count > 0)
{
ExistNode(treeViews);
}
else
{
NoNode(treeViews);
}
if (!string.IsNullOrWhiteSpace(FatherNode))
{
foreach (TreeViewItem item in this.portionFunctions.Items)
{
if (item.Uid == FatherNode)
{
item.Items.Add(treeViews);
break;
}
bool isInsert = InsertNode(item, treeViews);
if (isInsert) break;
}
}
else
{
if (!string.IsNullOrWhiteSpace(treeViews.Uid))
{
this.portionFunctions.Items.Add(treeViews);
}
}
}
/// <summary>
/// 检查是否存在父元素
/// </summary>
/// <param name="tree"></param>
private void CheckElement(DataRow tree)
{
if (!string.IsNullOrWhiteSpace(tree["SuperiorID"].ToString()))
{
DataRow treeInfo = dataTable.Select("ID =" + tree["SuperiorID"].ToString()).FirstOrDefault();
if (treeInfo == null) return;
//插入栈
stack.Push(treeInfo);
//如果上级ID不为空
if (!string.IsNullOrWhiteSpace(treeInfo["SuperiorID"].ToString()))
{
CheckElement(treeInfo);
}
}
}
#region 不存在节点
/// <summary>
/// 不存在节点
/// </summary>
public void NoNode(TreeViewItem treeViews)
{
//存在父节点
if (stack.Count > 0)
{
DataRow system = stack.Pop();
treeViews.Uid = system["ID"].ToString();
treeViews.Header = system["Name"].ToString();
ReturnsElement(treeViews);
}
else
{
treeViews.Uid = draggedItem.Uid;
treeViews.Header = draggedItem.Header;
foreach (TreeViewItem item in draggedItem.Items)
{
addChild(item, treeViews);
}
}
}
#endregion
#region 已存在节点
/// <summary>
/// 存在节点
/// </summary>
/// <param name="treeViews"></param>
public void ExistNode(TreeViewItem treeViews)
{
//存在父节点
if (stack.Count > 0)
{
CheckNodes(treeViews);
}
else
{
foreach (TreeViewItem item in this.portionFunctions.Items)
{
if (draggedItem.Uid == item.Uid)
{
if (draggedItem.Items.Count > 0)
{
this.portionFunctions.Items.Remove(item);
break;
}
else
{
return;
}
}
}
treeViews.Uid = draggedItem.Uid;
treeViews.Header = draggedItem.Header;
foreach (TreeViewItem item in draggedItem.Items)
{
addChild(item, treeViews);
}
}
}
/// <summary>
/// 检查节点是否已存在
/// </summary>
/// <param name="treeViews">目标节点</param>
private void CheckNodes(TreeViewItem treeViews)
{
//是否存在节点
bool isExist = false;
//第一次判断
if (treeViews.Items.Count == 0)
{
if (stack.Count > 0)
{
DataRow system = stack.Pop();
foreach (TreeViewItem item in this.portionFunctions.Items)
{
if (system["ID"].ToString() == item.Uid)
{
isExist = true;
CheckNodes(item);
return;
}
}
if (!isExist)
{
treeViews.Uid = system["ID"].ToString();
treeViews.Header = system["Name"].ToString();
ReturnsElement(treeViews);
}
}
}
else
{
if (stack.Count > 0)
{
DataRow system = stack.Pop();
foreach (TreeViewItem item in treeViews.Items)
{
if (system["ID"].ToString() == item.Uid)
{
isExist = true;
CheckNodes(item);
return;
}
}
//不存在
if (!isExist)
{
treeViews.Uid = system["ID"].ToString();
treeViews.Header = system["Name"].ToString();
if (!string.IsNullOrWhiteSpace(system["SuperiorID"].ToString()))
{
//记录父节点
FatherNode = system["SuperiorID"].ToString();
}
ReturnsElement(treeViews);
}
}
//拖拽的父节点都存在,判断拖拽的节点是否存在
else
{
foreach (TreeViewItem item in treeViews.Items)
{
//如果存在,那么删除原来的
if (item.Uid == draggedItem.Uid)
{
if (draggedItem.Items.Count > 0)
{
//从目标节点将原来的节点删除
treeViews.Items.Remove(item);
break;
}
else
{
return;
}
}
}
//添加节点
TreeViewItem viewItem = new TreeViewItem();
viewItem.Uid = draggedItem.Uid;
viewItem.Header = draggedItem.Header;
treeViews.Items.Add(viewItem);
foreach (TreeViewItem treeViewItem in draggedItem.Items)
{
addChild(treeViewItem, viewItem);
}
}
}
}
#endregion
/// <summary>
/// 返回父节点元素
/// </summary>
/// <param name="treeViews"></param>
public void ReturnsElement(TreeViewItem treeViews)
{
TreeViewItem tree = new TreeViewItem();
if (stack.Count > 0)
{
DataRow system = stack.Pop();
tree.Uid = system["ID"].ToString();
tree.Header = system["Name"].ToString();
treeViews.Items.Add(tree);
ReturnsElement(tree);
}
else
{
tree.Uid = draggedItem.Uid;
tree.Header = draggedItem.Header;
treeViews.Items.Add(tree);
foreach (TreeViewItem item in draggedItem.Items)
{
addChild(item, tree);
}
}
}
/// <summary>
/// 添加子节点
/// </summary>
/// <param name="_sourceItem">子节点</param>
/// <param name="_treeViewItem">目标节点</param>
private void addChild(TreeViewItem _sourceItem, TreeViewItem _treeViewItem)
{
// 在目标树状视图中添加项目
TreeViewItem item1 = new TreeViewItem();
// 在目标树状视图中添加项目
item1.Header = _sourceItem.Header;
item1.Uid = _sourceItem.Uid;
_treeViewItem.Items.Add(item1);
foreach (TreeViewItem item in _sourceItem.Items)
{
addChild(item, item1);
}
}
/// <summary>
/// 插入节点(需要插入的位置)
/// </summary>
/// <param name="treeView">目标节点</param>
/// <param name="tree">拖拽节点</param>
private bool InsertNode(TreeViewItem treeView, TreeViewItem tree)
{
foreach (TreeViewItem item in treeView.Items)
{
if (item.Uid == FatherNode)
{
item.Items.Add(tree);
return true;
}
InsertNode(item, tree);
}
return false;
}
最后上张图: