что является лучшим способом построить элемент управления представления дерева, используя коллекцию строк - PullRequest
0 голосов
/ 14 декабря 2011

Я пытаюсь подготовить элемент управления представлением дерева из следующих строк.

    "US|New York|D.M.Street"
    "US|New York|ShoppingMall"
    "INDIA|Dehli|G.M. Road"
    "INDIA|Mumbai|Harbour Street"
    "US|Washington|WhiteHouse"
    "INDIA|Dehli|Rajpath"
    "INDIA|Mumbai|CST"

Я хочу заполнить представление дерева из этой коллекции в C #.следующим образом

Country
|
US => NewYork   ==========>D.M.Street
|      |        ==========>ShoppingMall
       |
|      Washinton==========>WhiteHouse
|
INDIA=>Dehli    ==========>G.M. Road
      |         ==========>Rajpath
      |
      Mumbai    ==========>CST
                ==========>Harbour Street

как я могу подготовить это?коллекция или еще способ?

Ответы [ 2 ]

1 голос
/ 14 декабря 2011

Учитывая функцию GetData(), которая возвращает IEnumerable<string> со всеми строковыми данными, и при условии, что вы хотите перемешать LINQ:

  var nodes = GetData().Select(data => data.Split('|')).GroupBy(x => x[0]).Select(
    country => new TreeNode(country.Key, country.GroupBy(x => x[1]).Select(
      city => new TreeNode(city.Key, city.Select(
        place => new TreeNode(place[2]))
        .ToArray()))
      .ToArray()))
    .ToArray();

  treeView1.Nodes.AddRange(nodes);

enter image description here

Обратите внимание, что это не учитывает противоречивые варианты написания "Нью-Йорк" и "Мумбаи" в ваших данных выборки, которые я исправил в выборке.

1 голос
/ 14 декабря 2011

Вот как бы я подошел к этому:

Создание класса и коллекции для хранения вложенной иерархии элементов (это может быть расширено позже, если потребуется больше подробностей).

public class Element
{
    public Element(string Name)
    {
        this.Name = Name;
    }
    public string Name { get; set; }

    public ElementCollection Children = new ElementCollection();

    // This method is used to add the specified child name if it does not currently 
    // exist, or return the existing one if it does
    public Element AddOrFetchChild(string sName)
    {
        Element oChild;
        if (this.Children.ContainsKey(sName))
        {
            oChild = this.Children[sName];
        }
        else
        {
            oChild = new Element(sName);
            this.Children.Add(sName, oChild);
        }
        return oChild;
    }        

}

public class ElementCollection : System.Collections.Generic.Dictionary<string, Element>
{

}

Затем проанализируйте ваши данные в коллекции (обратите внимание, что это будет поддерживать любой уровень вложенности в вашей структуре записей без необходимости изменения кода):

        string[] asLines;

        // ToDo: Add code here to populate the collection of lines to process

        // Create a base element that makes popuplation of the elements easier
        Element BaseElement = new Element("");

        // Cycle through each of the lines
        foreach (string sLine in asLines())
        {
            // Get the components out of the line
            string[] asElements = sLine.Split("|");

            // Starting with the base element
            Element oParentElement = BaseElement;

            // Cycle through each of the elements that were found, adding the current value to the parent's 
            // collection of children, then using the new or found item as the parent for the next item in the list
            for (int nI = 0; nI < asElements.Length; nI++)
            {
                oParentElement = oParentElement.AddOrFetchChild(asElements[nI]);
            }
        }

        // Finally, add the nodes to the tree recursively
        AddNodesToTree(BaseElement.Children, this.treeView1.Nodes);

и это рекурсивный метод, используемый для добавления элементов в дерево

    /// <summary>
    /// A recursive method to add all of the records to the specified collection of nodes
    /// </summary>
    /// <param name="cRecords"></param>
    /// <param name="cNodes"></param>
    private void AddNodesToTree(ElementCollection cRecords, TreeNodeCollection cNodes)
    {
        foreach (Element oRecord in cRecords.Values)
        {
            TreeNode oNode = new TreeNode();
            oNode.Text = oRecord.Name;
            oNode.Tag = oRecord;
            cNodes.Add(oNode);
            // Now add the node's children if any
            if (oRecord.Children.Count != 0)
            {
                AddNodesToTree(oRecord.Children, oNode.Nodes);
            }
        }

    }
...