ツリービューのノードの表示順序を入れ替えるには?

解決


エレクトリックトーマス  2005-06-16 00:40:47  No: 122685  IP: [192.*.*.*]

VB6での質問です。
ツリービューで下記のようなツリーを最初に作った後

|_アイテム1
|      |__アイテム11
|      |__アイテム12
|      |__アイテム13
|_アイテム2
        |__アイテム21
        |__アイテム22
        |__アイテム23

アイテム1とアイテム2の表示順序を子ノード共まとめて入れ替えたいのですが
どのようにすればできるのでしょうか?

|_アイテム2
|      |__アイテム21
|      |__アイテム22
|      |__アイテム23
|_アイテム1
        |__アイテム11
        |__アイテム12
        |__アイテム13

ソートによる並べ替えでなく任意の並べ替えを行いたいと思っています。
実際はマウスドラッグにより順序を入れ替えれたらいいのですが、まずコード
で順序の入れ替えを行いたいと考えています。

  Dim objNd1  As Node
  Dim objNd2  As Node
  
  Set objNd1 = TreeView1.Nodes(1)
  Set objNd2 = TreeView1.Nodes(1).Next

  Set TreeView1.Nodes(1) = objNd2
  Set TreeView1.Nodes(1).Next = objNd1

のように書いてみたのですがSet TreeView1.Nodes(1) = objNd2でコンパイルエラーと
なってしまいます。

よろしくお願いします。

編集 削除
特攻隊長まるるう  2005-06-16 00:47:44  No: 122686  IP: [192.*.*.*]

過去ログ検索『TreeView』でよく似たサンプルが引っかかりますが?

編集 削除
エレクトリックトーマス  2005-06-16 10:41:01  No: 122687  IP: [192.*.*.*]

回答ありがとうございます。
検索不足でした。

過去ログを参考に、ノードを新しく作り、移動するノードの要素をコピーし
子ノードの親ノードを新しく作ったノードに書き換えるというやり方を
作ってみました。

しかし、子ノードの1つはちゃんと親ノードに付いて移動するのですが
残りの子ノードが消えてしまいます。

どうも下記ソースの
  Do While Not c Is Nothing
    Set c.Parent = m
    Set c = c.Next
  Loop
が子ノードは複数あるのに1回しかループしていないためと分かりました。
なぜ1回しか回らないのでしょうか?
これを回避する方法はどうしたらよいのでしょう。


’最初に実行するプロシージャ
Private Sub Command1_Click()

  MoveNode TreeView1.Nodes, TreeView1.Nodes(1), TreeView1.Nodes(1).Next

End Sub


'  ns    : TreeView.Nodes
'  SrcNd : 移動するノード
'  TgtNd : SrcNd移動先の直前のノード(Nothingの時は先頭に移動する)
'
Public Sub MoveNode(ns As Nodes, SrcNd As Node, TgtNd As Node)

  Dim m As Node
  Dim c As Node
  
  
  If TgtNd Is Nothing Then
    Set m = ns.Add(SrcNd.Index, tvwFirst, , SrcNd.Text, SrcNd.Image, SrcNd.SelectedImage)
  Else
    Set m = ns.Add(TgtNd.Index, tvwNext, , SrcNd.Text, SrcNd.Image, SrcNd.SelectedImage)
  End If
  
  Set c = SrcNd.Child.FirstSibling
  Do While Not c Is Nothing           '<--------ここが1回で終わる
    Set c.Parent = m
    Set c = c.Next
  Loop
  
  ns.Remove SrcNd.Key
  
  m.Key = SrcNd.Key
  
  Set SrcNd = Nothing
  Set m = Nothing
  
End Sub

編集 削除
特攻隊長まるるう  2005-06-16 13:08:55  No: 122688  IP: [192.*.*.*]

>    Set c.Parent = m
した時点で c は移動先に移ってるんだから、『次の Node』
とか指定されても、まだ1個しか移動してないんだから存在
しないよね。

編集 削除
エレクトリックトーマス  2005-06-16 17:00:58  No: 122689  IP: [192.*.*.*]

ノードの親ノードを書き換えた時点で、そのノードは以前とは
別グループになってしまうのでNextでは次を得られないという
こだと理解しました。
そこで予め次のノードを取得することにより解決しました。

  Set c = SrcNd.Child.LastSibling
  Do While Not c Is Nothing
    Set c2 = c.Previous
    Set c.Parent = m
    Set c = c2
  Loop

ただ、最初は  Set c = SrcNd.Child.FirstSiblingとしていたのですが
これだとなぜか子ノードの順序が最初と逆になってしまうのでLastSibling
からしましたが、そういうものなのでしょうか。

とにかく無事目的の動作を作る事ができ、解決とします。
ありがとうございました。

編集 削除
特攻隊長まるるう  2005-06-16 17:37:25  No: 122690  IP: [192.*.*.*]

>  Set c = SrcNd.Child.LastSibling
SrcNd に子供がいないと落ちるかな?

SrcNd に子供がいたら順に移動先に設定…文章どおりコーディングすると
[VB6.0]
    Me.TreeView1.Visible = False 'Node が沢山あると重くなるので非表示
    Do While Not SrcNd.Child Is Nothing
        Set c = SrcNd.Child.LastSibling
        Set c.Parent = m
    Loop
    Me.TreeView1.Visible = True

でどうでしょう?。

>ただ、最初は  Set c = SrcNd.Child.FirstSiblingとしていたのですが
>これだとなぜか子ノードの順序が最初と逆になってしまうのでLastSibling
>からしましたが、そういうものなのでしょうか。
このヘンあまり調べてないので説明できないけど、TreeView 側の管理が
人間の見た目の感覚とずれてる所に原因があるかと思います。ボタンを何回か
押してみて下さい。Nodes の Index がどう変わってるか調べてみると
何か分かるかも?。ある Node の子に設定するのに子の最後に追加するため
には子をすべて検索しないといけないわけだし、その辺かなぁ???

編集 削除
エレクトリックトーマス  2005-06-16 18:03:33  No: 122691  IP: [192.*.*.*]

確かにSrcNd.ChildがNothingの時はエラーになります。
提示して頂いた方法の考え方(移動もとの子ノードがなくなる
までループ)だとコード量も少なくて明快ですね。

ありがとうございました。
解決を押し忘れてましたので解決とします。

編集 削除