目次

TreeViewのNodeコレクションの状態をSQLiteに保存する

まず、保存するためのテーブルを設計します。
【SQLite】

CREATE TABLE "TREEVIEW" (
	"ROWNAME"	TEXT,
	"hasChild"	INTEGER NOT NULL DEFAULT 0,
	"parentName"	TEXT NOT NULL,
	"index"	INTEGER NOT NULL,
	PRIMARY KEY("ROWNAME")
);

【C#】

using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace learning
{
    public partial class Form1 : Form
    {
 
        public Form1()
        {
            InitializeComponent();
        }
 
 
 
        private void Form1_Load(object sender, EventArgs e)
        {
            //https://dobon.net/vb/dotnet/control/tvdraganddrop.html
            //TreeView1へのドラッグを受け入れる
            treeView1.AllowDrop = true;
            //イベントハンドラを追加する
            treeView1.ItemDrag +=
                new ItemDragEventHandler(TreeView1_ItemDrag);
            treeView1.DragOver +=
                new DragEventHandler(TreeView1_DragOver);
            treeView1.DragDrop +=
                new DragEventHandler(TreeView1_DragDrop);
        }
 
 
                private void button2_Click(object sender, EventArgs e)
        {
            treeView1.Nodes.Clear();
 
            var connectionString = "Data Source=learning.db";
            using (var cn = new SQLiteConnection(connectionString))
            {
                cn.Open();
                using (var cmd = new SQLiteCommand(cn))
                {
                    using (var context = new DataContext(cn))
                    {
 
 
                        Dictionary<int, TreeNode> Dtree = new Dictionary<int, TreeNode>();
                        TREEVIEW[] clone = context.GetTable<TREEVIEW>().ToArray().Clone() as TREEVIEW[];
 
                        foreach (var q in context.GetTable<TREEVIEW>().ToArray().OrderBy(y => y.index))
                        {
                            Dtree.Add(q.index, new TreeNode(q.ROWNAME));
                        }
 
                        foreach (var q in context.GetTable<TREEVIEW>().ToArray().OrderByDescending(y => y.index))
                        {
                            var name = q.ROWNAME;
                            var pare = q.parentName;
                            if (pare != "ROOT")
                            {
                                var gg = clone.Single(x => x.ROWNAME == pare);
                                Dtree[gg.index].Nodes.Insert(0,Dtree[q.index].Clone() as TreeNode);
                                Dtree.Remove(q.index);
                            }
                        }
 
                        foreach(var q in context.GetTable<TREEVIEW>().ToArray().Where(y => y.parentName == "ROOT").OrderBy(z => z.index))
                        {
                            treeView1.Nodes.Add(Dtree[q.index]);
                        }
                    }
                }
 
            }
 
            treeView1.ExpandAll();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
 
            treeToDb(treeView1.Nodes);
 
 
        }
 
        private void treeToDb(TreeNodeCollection tnc)
        {
            var connectionString = "Data Source=learning.db";
            int c = 0;
            using (var cn = new SQLiteConnection(connectionString))
            {
                cn.Open();
                using (var cmd = new SQLiteCommand(cn))
                {
                    using (var context = new DataContext(cn))
                    {
 
                        context.ExecuteCommand("DELETE FROM TREEVIEW");
                        var views = context.GetTable<TREEVIEW>();
 
                        recursiveTree(views, context, tnc, ref c);
 
                    }
                }
 
            }
        }
 
        private void recursiveTree(Table<TREEVIEW> table, DataContext dc, TreeNodeCollection treeNodeCollection, ref int C)
        {
            foreach (TreeNode tnn in treeNodeCollection)
            {
 
 
                var Rowname = tnn.Text;
                var hAschild = tnn.GetNodeCount(true) > 0 ? 1 : 0;
                var lEvel = tnn.Level;
                var parent = tnn.Parent is null ? "ROOT" : tnn.Parent.Text;
                var kind = tnn.ImageIndex;
 
                table.InsertOnSubmit(new TREEVIEW(Rowname, hAschild, parent,C));
                dc.SubmitChanges();
                C++;
 
                if (hAschild == 1)
                {
                    recursiveTree(table, dc, tnn.Nodes, ref C);
                }
            }
        }
    }
 
    [Table(Name = "TREEVIEW")]
    public class TREEVIEW
    {
 
        [Column(Name = "ROWNAME", CanBeNull = false, DbType = "NVARCHAR", IsPrimaryKey = true)]
        public string ROWNAME { get; set; }
 
        [Column(Name = "hasChild", CanBeNull = false, DbType = "int", IsPrimaryKey = false)]
        public int hasChild { get; set; }
 
        [Column(Name = "parentName", CanBeNull = false, DbType = "NVARCHAR", IsPrimaryKey = false)]
        public string parentName { get; set; }
 
        [Column(Name = "index", CanBeNull = false, DbType = "int", IsPrimaryKey = false)]
        public int index { get; set; }
 
        public TREEVIEW() { }
 
        public TREEVIEW(string rowname, int HasChild, string ParentName,int Index)
        {
            ROWNAME = rowname;
            hasChild = HasChild;
            parentName = ParentName;
            index = Index;
 
        }
 
 
 
    }
}

より、ドラッグ&ドロップでNodeを移動できるようにしておくと便利です。(上記コード内にはメソッド名のみ記載しています。)

実行結果