如何将文本文件大纲列表转换为递归的对象集合?

Edw*_*uay 7 c# treeview recursion design-patterns

如何将此文本文件内容转换为可以绑定到TreeView递归对象集合?也就是说我希望得到一个由3个对象组成的集合,第一个称为拥有三个子对象集合的国家:法国,德国,意大利等等......

答案:感谢所有帮助过这方面的人,这是我的代码,它成功地将此文本大纲解析为XAML树:http://tanguay.info/web/index.php?pt = codeExamples&id = 358

countries
-france
--paris
--bordeaux
-germany
-italy
subjects
-math
--algebra
--calculus
-science
--chemistry
--biology
other
-this
-that
Run Code Online (Sandbox Code Playgroud)

下面代码是我得到的,但它没有正确处理多个父母的孩子.

using System;
using System.Collections.Generic;
using System.Text;

namespace TestRecursive2342
{
    class Program
    {
        static void Main(string[] args)
        {
            List<OutlineObject> outlineObjects = new List<OutlineObject>();

            //convert file contents to object collection
            List<string> lines = Helpers.GetFileAsLines();
            Stack<OutlineObject> stack = new Stack<OutlineObject>();
            foreach (var line in lines)
            {
                OutlineObject oo = new OutlineObject(line);

                if (stack.Count > 0)
                {
                    OutlineObject topObject = stack.Peek();
                    if (topObject.Indent < oo.Indent)
                    {
                        topObject.OutlineObjects.Add(oo);
                        stack.Push(oo);
                    }
                    else
                    {
                        stack.Pop();
                        stack.Push(oo);                        
                    }

                }
                else
                {
                    stack.Push(oo);
                }

                if(oo.Indent == 0)
                    outlineObjects.Add(oo);
            }

            outlineObjects.ForEach(oo => Console.WriteLine(oo.Line));

            Console.ReadLine();
        }
    }

    public class OutlineObject
    {
        public List<OutlineObject> OutlineObjects { get; set; }
        public string Line { get; set; }
        public int Indent { get; set; }

        public OutlineObject(string rawLine)
        {
            OutlineObjects = new List<OutlineObject>();
            Indent = rawLine.CountPrecedingDashes();
            Line = rawLine.Trim(new char[] { '-', ' ', '\t' });
        }
    }

    public static class Helpers
    {
        public static List<string> GetFileAsLines()
        {
            return new List<string> {
                "countries",
                "-france",
                "--paris",
                "--bordeaux",
                "-germany",
                "-italy",
                "subjects",
                "-math",
                "--algebra",
                "--calculus",
                "-science",
                "--chemistry",
                "--biology",
                "other",
                "-this",
                "-that"};
        }

        public static int CountPrecedingDashes(this string line)
        {
            int tabs = 0;
            StringBuilder sb = new StringBuilder();
            foreach (var c in line)
            {
                if (c == '-')
                    tabs++;
                else
                    break;
            }
            return tabs;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Tom*_*asi 2

public class Item
{
    public string Name;
    public Item Parent;
}

List<Item> Collection = new List<Item>();

public void Main()
{
    var DataSource = data.InnerText;

    StreamReader Reader = new StreamReader(MapPath("_test2.txt"));
    int LastLevel = 0;

    while (Reader.EndOfStream == false) {
        var line = Reader.ReadLine();
        var Level = line.Where((System.Object c) => c == "-").Count;
        Item LastItem = default(Item);

        if (Collection.Count != 0) {
            LastItem = Collection.Last();
        }

        if (Level == 0) {
            Collection.Add(new Item { Name = line });
            LastLevel = 0;
        }
        else if (Level - LastLevel == 1) {
            Collection.Add(new Item { Name = line, Parent = LastItem });
            LastLevel += 1;
        }
        else if (Level == LastLevel) {
            Collection.Add(new Item { Name = line, Parent = LastItem.Parent });
        }
        else if (Level < LastLevel) {
            var LevelDiff = LastLevel - Level;
            Item Parent = LastItem;

            for (i = 0; i <= LevelDiff; i++) {
                Parent = Parent.Parent;
            }

            LastLevel = Level;
            Collection.Add(new Item { Name = line, Parent = Parent });
        }
    }

    Reader.Close();
}
Run Code Online (Sandbox Code Playgroud)

这应该可以解决问题。我在你的文本文件上测试了它。可能存在一些错误。测试一下并判断它是否有效。

编辑:实际上,经过进一步测试后发现这并不能按预期工作。您需要添加更多逻辑才能使其正常工作。我把这个留给你。

编辑:在对代码进行更多测试后,我得到了一个效果更好的版本。我仍然不能保证它在所有情况下都有效。