0

私は2つ持っていTreeViewます。
最初のものはこのように設計されています:

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

2つ目は空です。

ドラッグアンドドロップシステムを実装したので、ユーザーは最初のツリービューから2番目のツリービューにドラッグして塗りつぶすことができます。
ノードをドラッグするTreeViewと、彼のすべての親ノードと子ノードが表示されます。兄弟ではありません

例 :

ドラッグするC2と、2番目TreeViewは次のようになります

A
|--B1
   |--C2

C1も追加することにした場合は、次のようになります。

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

私はこのような複製を望んでいません:

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

したがって、ここから2つの質問があります(ドラッグアンドドロップがすでにこのように実装されており、親または子なしで選択されたノードのみを追加することを考慮して)。

  • 兄弟ではなく子と親でノードを持ってくるにはどうすればよいですか。それも可能ですか?
  • 最初の質問に答えて、すべての親ノードと子ノードを持つノードを追加するアルゴリズムを使用したら、ツリー全体を2回書き直さずに、兄弟で更新するにはどうすればよいですか?
4

2 に答える 2

1

いくつかのトレントクライアントのGUIを作成するときも同じタスクがあります。
トレントを開くと、トレントに含まれるファイルとフォルダを含むツリービューが表示されます。
解決方法:
ファイルパスのリストがあり、最初にそれを並べ替えてから、この関数を使用して並べ替えられたリストのアイテムをツリービューに追加します

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 に答える
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 に答える