2012-12-10 82 views
0

我有兩個TreeView
第一個是這樣設計:更新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 

所以我有兩個問題(考慮到拖放已經實現,如this,只添加沒有父母或孩子的選定節點)。

  • 我該如何讓節點與孩子和父母,而不是兄弟姐妹。它甚至有可能嗎?
  • 一旦第一個問題得到解答,並且我有一個算法來添加一個包含所有父節點和子節點的節點,那麼如何在不重寫整個樹的情況下更新一個兄弟節點?

回答

1

我爲一些torrent客戶端編寫gui時有同樣的任務。
當打開洪流時,應顯示包含文件和文件夾的樹視圖。
如何解決這個問題呢:
我有文件pathes的列表,第一我做什麼我已經整理,然後將排序列表中的項目與此功能的TreeView

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,但我認爲你可以理解這個想法。

+0

這是一個小到具體的您的具體情況。用一種我從未使用過的技術的語言。我有點想法,但仍然無法找到一種方法來解釋我的情況。不管怎麼說,還是要謝謝你 – phadaphunk

1

您的目的地Treeview更改TreeViewDragDrop

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); 
}