ノードを名前順にソートします。TreeNodeをソートするのであればTreeView.Sortメソッドを使えばいいのですが、選択しているノードの子ノードだけをソートするのであればどうすればいいのでしょうか?
選択されているノードの子ノードは以下の方法で取得できます。
1 2 3 4 5 6 7 |
List<TreeNode> childrenNode = new List<TreeNode>(); TreeNode node = treeView1.SelectedNode; var nodes = node.Nodes; foreach (TreeNode node0 in nodes) { childrenNode.Add(node0); } |
あとはLINQのOrderByを使って並べ替えます。選択されているノードの子ノードはいったん削除して挿入しなおします。
1 2 3 4 5 6 |
var children = childrenNode.OrderBy(x => x.Text); node.Nodes.Clear(); foreach (var node1 in children) { node.Nodes.Add(node1); } |
同じようにすればできそうです。
俺的ライブラリをつくる 同期化されたTreeView編
これに以下を付け加えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
namespace SyncTreeViewLib { public partial class SyncTreeView : UserControl { public void Sort(TreeNodeEx nodeEx) { if (nodeEx == null) return; string name = nodeEx.Key; List<TreeNode> nodeList = new List<TreeNode>(); foreach (TreeViewEx viewEx in this.SyncGroup.TreeViews) { TreeNode[] nodes = viewEx.Nodes.Find(name, true); if (nodes.Length == 1) nodeList.Add(nodes[0]); else throw new Exception("例外:Sort()内"); } foreach(TreeNode selectednode in nodeList) { TreeView view = selectednode.TreeView; TreeNode oldSelectedNode = view.SelectedNode; List<TreeNode> childrenNode = new List<TreeNode>(); var nodes = selectednode.Nodes; foreach (TreeNode node0 in nodes) { childrenNode.Add(node0); } var children = childrenNode.OrderBy(x => x.Text); selectednode.Nodes.Clear(); foreach (var node1 in children) { selectednode.Nodes.Add(node1); } view.SelectedNode = oldSelectedNode; } } } } |
俺的アウトラインプロセッサ側では
1 2 3 4 5 6 7 8 9 10 11 |
public partial class Form1 : Form { private void SortToolStripMenuItem_Click(object sender, EventArgs e) { ignoreSelectedNodeChange = true; TreeNodeEx nodeEx = syncTreeViewEx1.SelectedNode; syncTreeViewEx1.Sort(nodeEx); SetPageNumbers(); ignoreSelectedNodeChange = false; } } |
これでソートはできます。ソートに伴って選択されているアイテムが変更されるかもしれないので、フィールド変数 ignoreSelectedNodeChangeを使って制御しています。
また更新日時順(新しい順、古い順)といったSyncTreeViewにはない要素でソートしたい場合もあるかもしれません。
そこで・・・
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
public partial class Form1 : Form { private void SortToolStripMenuItem_Click(object sender, EventArgs e) { ignoreSelectedNodeChange = true; MySort(); ignoreSelectedNodeChange = false; return; } // 更新日時順に並べる private void MySort() { TreeNodeEx nodeEx = syncTreeViewEx1.SelectedNode; TreeNodeEx tempNode = syncTreeViewEx1.AddNodePrev(nodeEx, "", 0, 0, new Data()); List<TreeNodeEx> childrenNode = new List<TreeNodeEx>(); while (nodeEx.FirstNode != null) { TreeNodeEx treeNodeEx = nodeEx.FirstNode; childrenNode.Add(treeNodeEx); syncTreeViewEx1.MoveToLastChild(treeNodeEx, tempNode); } var children = childrenNode.OrderBy(x => GetData(x).RichData.SaveTime); foreach (var child in children) { syncTreeViewEx1.MoveToLastChild(child, nodeEx); } syncTreeViewEx1.DeleteNode(tempNode); SetPageNumbers(); } } |
これでソートもできるようになりました。
こんにちはテイネです。
記事「複数のTreeViewの内容を同期する」がビジュアル的に面白そうだなと思ったのですが、まったく動かすことができませんでした。
最終的にアウトラインプロセッサーにつながっているのだと分かり、ここに辿り着きました。
可能であれば、アウトラインプロセッサーのソースをまるごと頂きたいのですが、よろしくお願い致します。
これは大分前に作ったものなのでソースを処分してしまったようです。しばらくお待ち下さい