2011年4月21日木曜日

WindowsForms + C# : ツリービュー、ノードの順番入れ替え

  • ツリービューにおけるノードの順番の入れ替え。構造化テキストエディタとかだと順番重要。
  • XMLで書いたフィルタに対するエディタを作成していて必要になったので。
  • ソートはあるが、順番の入れ替えは、機能的に準備されてない。
  • ウェブ眺めて情報がないわけではなかったが、全部要素を消してループ書いて入れ替えとか面倒じゃないか
private void MoveTreeNodeInSiblings(Boolean upward)
{
//要素をCloneしてコピーすると比較的簡単に入れ替えられる//

TreeNode nodeClone = (TreeNode)treeViewFolder.SelectedNode.Clone();
TreeNode node = (TreeNode)treeViewFolder.SelectedNode;
TreeNode fowardNode = upward?node.PrevNode:node.NextNode;

if (node.Parent == null) {
MessageBox.Show("最上位の要素の入れ替えはできません");
return;
}

//参照のコピー
TreeNode ParentClone = (TreeNode)node.Parent.Clone();
IEnumerator en = ParentClone.Nodes.GetEnumerator();
TreeNode ParentRef = node.Parent;

int nodeHash = node.Tag.GetHashCode();//タグにデータが入ってること前提
int fowardHash = fowardNode.Tag.GetHashCode();

node.Parent.Nodes.Clear();//入れ替えのために消す

treeViewFolder.Visible = false;//描画対策
//基本的にクローンした要素に差し替える工程
while (en.MoveNext()) {
TreeNode tn = (TreeNode)en.Current;
if (fowardHash== tn.Tag.GetHashCode()) {
if (upward) {
ParentRef.Nodes.Add(nodeClone);
ParentRef.Nodes.Add(tn);
} else {
ParentRef.Nodes.Add(tn);
ParentRef.Nodes.Add(nodeClone);
}

} else if (nodeHash == tn.Tag.GetHashCode()) {
/*Skip*/
} else {
ParentRef.Nodes.Add(tn);
}
}
treeViewFolder.Visible = true;
treeViewFolder.SelectedNode = nodeClone;
treeViewFolder.Focus();
}