0

我有两个TreeView
第一个是这样设计的:

A
|--B1
   |--C1
   |--C2
|--B2
   |--C3
|--B3

第二个是空的。

我实现了一个拖放系统,因此用户可以从我的第一个树视图拖动到第二个树视图来填充它。
当一个节点被拖入时,TreeView我希望它带上他所有的父节点和子节点。不是兄弟姐妹

例子 :

如果我拖动C2,我的第二个TreeView应该是这样的

A
|--B1
   |--C2

如果我也决定添加C1,它应该如下所示:

A
|--B1
   |--C1
   |--C2

我不想要这样的重复:

 A
|--B1
   |--C2
 A
|--B1
   |--C1

所以我从这里有两个问题(考虑到拖放已经像这样实现,并且只添加了没有父母或孩子的选定节点)。

  • 我怎样才能把节点带到孩子和父母身上,而不是兄弟姐妹身上。甚至可能吗?
  • 一旦第一个问题得到回答并且我有一个算法来添加一个包含所有父节点和子节点的节点,我如何在不重写整个树两次的情况下使用兄弟节点进行更新?
4

2 回答 2

1

更改您TreeViewDragDrop的目的地Treeview

private void treeView_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
    TreeNode NewNode;

    if (e.Data.GetDataPresent("System.Windows.Forms.TreeNode", false))
    {
        NewNode = (TreeNode)e.Data.GetData("System.Windows.Forms.TreeNode");
        if (!(sender as TreeView).Nodes.Contains(NewNode))
        {
            //Add the droped node 
            List<TreeNode> tt = new List<TreeNode>();
            TreeNode tn = (TreeNode)NewNode.Clone();
            tt.Add(tn);

            //Prepare node with it's parents until the root note
            while ((TreeNode)NewNode.Parent is TreeNode)
            {
                TreeNode tnp = (TreeNode)NewNode.Parent.Clone();

                //prevent siblings to be added
                tnp.Nodes.Clear();

                tt.Add(tnp);
                NewNode = NewNode.Parent;
            }

            //Construct the structure of the treenote to be added to the treeview
            for (int i = tt.Count - 1; i > 0; i--)
            {
                tt[i].Nodes.Add(tt[i - 1]);
            }

            /*Add the whole structured treenode to the treeview*/


            TreeNode rootnote = ExistNotes((sender as TreeView), tt[tt.Count - 1]);
            if (rootnote != null)//Root node exists, add to the existing node
            {
                foreach (TreeNode tsub in tt[tt.Count - 1].Nodes)
                {
                    AddNote(rootnote, tsub);
                }
            }
            else//Root node not exist, add to the treeview as new node.
            {
                (sender as TreeView).Nodes.Add(tt[tt.Count - 1]);
            }

            //  NewNode.Remove();
        }
    }
}

辅助功能:

/// <summary>
/// Recursive function to add node
/// </summary>
/// <param name="tnbase">RootNode</param>
/// <param name="tn">Node to be added</param>
private void AddNode(TreeNode tnbase, TreeNode tn)
{
    bool exists = false;
    foreach (TreeNode rt in tnbase.Nodes)
    {
        if (this.IsNodesEquals(rt, tn))
        {
            foreach (TreeNode srt in tn.Nodes)
            {
                this.AddNode(rt, srt);
            }
            exists = true;
        }
    }
    if (!exists)
    {
        tnbase.Nodes.Add(tn);
    }
}

/// <summary>
/// Get exist node from the treeview
/// </summary>
/// <param name="tv">Treeview to check</param>
/// <param name="tn">Node to compare</param>
/// <returns></returns>
private TreeNode ExistNode(TreeView tv, TreeNode tn)
{
    TreeNode existsnote = null;
    foreach (TreeNode rt in tv.Nodes)
    {
        if (this.IsNodesEquals(rt, tn))
        {
            existsnote = rt;
        }
    }
    return existsnote;
}

/// <summary>
/// Compare two nodes by the text
/// </summary>
/// <param name="t1">node to compare</param>
/// <param name="t2">node to compare with</param>
/// <returns></returns>
private bool IsNodesEquals(TreeNode t1, TreeNode t2)
{
    return (t1 != null && t2 != null && t1.Text == t2.Text);
}
于 2012-12-18T10:36:38.863 回答
1

在为某些 torrent 客户端编写 gui 时,我有同样的任务。
打开 torrent 时,应显示包含 torrent 的文件和文件夹的树视图。
我该如何解决:
我有一个文件路径列表,首先我做了什么我已经对其进行了排序,然后使用此函数将排序列表的项目添加到树视图

void FileTreeModel::addPath( QString path,QString size )
{
path=QDir::toNativeSeparators(path);
QStringList pathparts=path.split(QDir::separator());

FileTreeItem *iterator=rootItem,*save=rootItem;
if (rootItem->childCount()==0)
{
    //qDebug() << "root item has no childs appending current path";
    FileTreeItem* curitem=rootItem;
    for (int i=0;i<pathparts.count();i++)
    {
        curitem->appendChild(new FileTreeItem(qMakePair(pathparts.at(i),i==pathparts.count()-1? size : ""),curitem));
        curitem = curitem->child(0);
    }
    rootItem=save;
    return;
}
for (int i=0;i<pathparts.count();i++)
{
    int foundnum=-1;
    for (int j=0;j<iterator->childCount();j++)
    {
        //qDebug() << iterator->child(j)->data(0) << " " << pathparts.at(i);
        if (iterator->child(j)->data(0).toString().compare(pathparts.at(i))==0) 
        {
            //qDebug() <<"Found :" << iterator->child(j)->data(0) << " " << pathparts.at(i);
            foundnum=j;
            break;
        }
    }

    if (foundnum >= 0)
    {
        iterator = iterator->child(foundnum);
    }
    else
    {
        //qDebug() << "appending new child" << pathparts.at(i)  << " to "  << iterator->data(0) ;
        iterator->appendChild(new FileTreeItem(qMakePair(pathparts.at(i),i==pathparts.count()-1? size : ""),iterator));
        iterator = iterator->child(iterator->childCount()-1);
        //qDebug() << "new iterator value" << iterator->data(0) ;
    }

}
    rootItem=save;

}

这是Qt,但我认为您可以理解这个想法。

于 2012-12-10T20:26:38.797 回答