Search code examples
wpffiletexttreeviewtreeviewitem

C# WPF: Create TreeView from text file


I create my TreeViewItems with the class Node . In the example nodes are specified in source code. But how do I do it if the nodes are to be imported from a text file with content like this:

text file content

Any ideas?

I have tried the following.

    public MainWindowVM()
    {
        private ObservableCollection<Node> mRootNodes;
        public IEnumerable<Node> RootNodes { get { return mRootNodes; } }
        List<string[]> TreeNodes = new List<string[]>();

        string[] lines = null;
        try
        {
            lines = System.IO.File.ReadAllLines(MainWindow.TextFilePath , System.Text.Encoding.Default);
        }
        catch (IOException ex)
        {
            MessageBox.Show(ex.Message);
            Environment.Exit(0);
        }
        if (lines == null || lines.Length == 0)
        {
            MessageBox.Show("Text file has no content!");
            Environment.Exit(0);
        }

        foreach (var line in lines)
        {
            TreeNodes.Add(line.Split('|'));
        }

        Node newNode = null;
        Node childNode = null;
        Node root = new Node() { Name = TreeNodes[0][0] };
        if (TreeNodes[0].Length > 1)
        {
            newNode = new Node() { Name = TreeNodes[0][1] };
            root.Children.Add(newNode);
        }
        for (int s = 2; s < TreeNodes[0].Length; s++)
        {
            childNode = new Node() { Name = TreeNodes[0][s] };
            newNode.Children.Add(childNode);
            newNode = childNode;
        }
    }

but I get only the first two nodes. I do not know how to build the whole TreeView with a loop.

TreeView


Solution

  • input example

    Root|A
    Root|B|C
    Root|B|D
    Root|E
    

    the problem with your code is that you only process TreeNodes[0] element. to process a collection of elements you need a loop

     public MainWindowVM()
    {
        private ObservableCollection<Node> mRootNodes;
        public IEnumerable<Node> RootNodes { get { return mRootNodes; } }
    
        string[] lines = null;
        try
        {
            lines = System.IO.File.ReadAllLines(MainWindow.TextFilePath , System.Text.Encoding.Default);
        }
        catch (IOException ex)
        {
            MessageBox.Show(ex.Message);
            Environment.Exit(0);
        }
        if (lines == null || lines.Length == 0)
        {
            MessageBox.Show("Text file has no content!");
            Environment.Exit(0);
        }
    
        Dictionary<string, Node> nodeCache = new Dictionary<string, Node>();
        // processing each line
        foreach (var line in lines)
        {                
            Node parentNode = null;
            string key = null;
            // in each line there are one or more node names, separated by | char
            foreach (string childNodeName in line.Split('|'))
            {
                Node childNode;
                // names are not unique, we need a composite key (full node path)
                key += "|" + childNodeName;
                // each node has unique key
                // if key doesn't exists in cache, we need to create new child node
                if (false == nodeCache.TryGetValue(key, out childNode))
                {
                    childNode = new Node { Name = childNodeName };
                    nodeCache.Add(key, childNode);
    
                    if (parentNode != null)
                        // each node (exept root) has a parent
                        // we need to add a child node to parent ChildRen collection
                        parentNode.Children.Add(childNode);
                    else 
                        // root nodes are stored in a separate collection
                        mRootNodes.Add(childNode);
                }
    
                // saving current node for next iteration
                parentNode = childNode;
            }
        }
    }