Winform TreeView节点保存与恢复,真正能做到状态恢复。

1、在winform里面安装NuGet包Newtonsoft.Json

2、新建类:TreeNodeStateHelper.cs

类代码:其中的Sunny.UI.UITreeView treeView可按实际控件进行修改。

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;

public class TreeNodeStateHelper
{
    public string SaveFilePath { get; set; }

    public TreeNodeStateHelper(string saveFilePath)
    {
        SaveFilePath = saveFilePath;
    }

    public class TreeNodeState
    {
        public string Text { get; set; }
        public List<TreeNodeState> Children { get; set; } = new List<TreeNodeState>();
        public bool IsExpanded { get; set; }
        public bool IsSelected { get; set; }
    }

    public void SaveTreeState(Sunny.UI.UITreeView treeView)
    {
        var rootStates = treeView.Nodes.Cast<TreeNode>().Select(SerializeNode).ToList();
        File.WriteAllText(SaveFilePath, JsonConvert.SerializeObject(rootStates, Formatting.Indented));
    }

    public void LoadTreeState(Sunny.UI.UITreeView treeView)
    {
        if (!File.Exists(SaveFilePath)) return;// 文件不存在

        try
        {
            var json = File.ReadAllText(SaveFilePath);
            var rootStates = JsonConvert.DeserializeObject<List<TreeNodeState>>(json);

            treeView.BeginUpdate();
            treeView.Nodes.Clear();

            // 1. 先构建树(不设置展开)
            var rootNodes = rootStates.Select(s => DeserializeNode(s, false)).ToArray();
            treeView.Nodes.AddRange(rootNodes);

            // 2. 再递归设置展开状态
            for (int i = 0; i < rootStates.Count; i++)
            {
                RestoreExpansionState(rootNodes[i], rootStates[i]);
            }

            treeView.EndUpdate();
        }
        catch (Exception ex)
        {
            MessageBox.Show($"状态加载失败: {ex.Message}");
        }
    }
    // 仅构建节点,不设置展开
    private TreeNode DeserializeNode(TreeNodeState state, bool dummy)
    {
        var node = new TreeNode(state.Text);
        node.Nodes.AddRange(state.Children.Select(c => DeserializeNode(c, false)).ToArray());
        return node;
    }
    // 递归恢复展开/折叠
    private void RestoreExpansionState(TreeNode node, TreeNodeState state)
    {
        if (state.IsExpanded)
            node.Expand();
        else
            node.Collapse();

        for (int i = 0; i < state.Children.Count; i++)
            RestoreExpansionState(node.Nodes[i], state.Children[i]);
    }
    private TreeNodeState SerializeNode(TreeNode node)
    {
        return new TreeNodeState
        {
            Text = node.Text,
            IsExpanded = node.IsExpanded,
            IsSelected = node.IsSelected,
            Children = node.Nodes.Cast<TreeNode>().Select(SerializeNode).ToList()
        };
    }

    private TreeNode DeserializeNode(TreeNodeState state)
    {
        var node = new TreeNode(state.Text);

        if (state.IsExpanded)
            node.Expand();
        else
            node.Collapse();

        node.Nodes.AddRange(state.Children.Select(DeserializeNode).ToArray());
        return node;
    }
}

使用:

1、先声明

private TreeNodeStateHelper _treeStateHelper;//树节点状态管理

 

2、使用前先创建对象,可以在InitializeComponent();后面创建,也可以在Load里面。

//创建对象
            _treeStateHelper = new TreeNodeStateHelper("Tree_state.json");

3、保存与恢复:在需要的地方添加保存与恢复功能。

_treeStateHelper.LoadTreeState(Tree_Rule);//恢复展开的节点
_treeStateHelper.SaveTreeState(Tree_Rule);//保存展开的节点

 

posted @ 2025-04-12 10:14  Cmale  阅读(58)  评论(0)    收藏  举报