如何转换为通用代码?

时间:2012-09-21 07:04:45

标签: c# treeview

我正在尝试按以下顺序创建包含项目的treeView。

+ Continent
    + Country
        + Province
            + Territory

而且,我有一个通用类来保存treeView Items数据。

public class TreeViewContinents
{
    public List<TreeViewContinents> Children { get; set; }    
    public TreeViewContinents Parent { get; set; }    
    public string Name { get; set; }    
    public string Content { get; set; }
}

数据:

private readonly List<Dictionary<string, object>> continentsList = new List<Dictionary<string, object>>();

/*
continentsList[0] - "Continent", "Asia"
                    "Country", "Afghanistan"
                    "Province", "Kabul"
                    "Territory", "Bagrami"
                    "Language", "aaa"
                    "Culture", "bbb"
                .
                .               
                .
                .

continentsList[n] - "Continent", "North America"
                    "Country", "Canada"
                    "Province", "Ontario"
                    "Territory", "Ottawa"
                    "Language", "aaa"
                    "Culture", "bbb

*/

基于需要生成树视图项的字符串数组。

var treeViewItemNames = new[] { "Continent", "Country", "Province", "Territory" };

代码:

List<object> Continents = this.continentsList.Where(
                            p_oDict => p_oDict.ContainsKey(treeViewItemNames[0]))
                            .Select( p_oDict => p_oDict[treeViewItemNames[0]])
                            .Distinct()
                            .ToList();

var topItems = new List<TreeViewContinents>();

foreach (object continent in Continents)
{
    var level1Items = new TreeViewContinents { Name = treeViewItemNames[0], Content = continent.ToString() };

    List<object> Countries = this.continentsList.Where(
                            p_oDict => p_oDict.ContainsKey(treeViewItemNames[0])
                            && p_oDict.ContainsKey(treeViewItemNames[1])
                            && p_oDict[treeViewItemNames[0]].Equals(continent)
                            .Select( p_oDict => p_oDict[treeViewItemNames[1]])
                            .Distinct()
                            .ToList();

    Countries.Sort((p_oU1, p_oU2) => string.Compare(p_oU1.ToString(), p_oU2.ToString(), StringComparison.Ordinal));
    foreach (object country in Countries)
    {
        var level2Items = new TreeViewContinents { Name = treeViewItemNames[1], Content = country.ToString(), Parent = level1Items };
        level1Items.Children.Add(level2Items);

        List<object> Provinces = this.continentsList.Where(
                               p_oDict => p_oDict.ContainsKey(treeViewItemNames[0])
                                        && p_oDict.ContainsKey(treeViewItemNames[1])
                                          && p_oDict.ContainsKey(treeViewItemNames[2])
                                          && p_oDict[treeViewItemNames[0]].Equals(continent)
                                          && p_oDict[treeViewItemNames[1]].Equals(country))
                                          .Select( p_oDict => p_oDict[treeViewItemNames[2]]).Distinct()
                                        .ToList();

        Provinces.Sort((p_oU1, p_oU2) => string.Compare(p_oU1.ToString(), p_oU2.ToString(), StringComparison.Ordinal));
        foreach (object province in Provinces)
        {
            var level3Items = new TreeViewContinents { Name = treeViewItemNames[2], Content = province.ToString(), Parent = level2Items };
            level2Items.Children.Add(level3Items);

            List<object> Territories = this.continentsList.Where(
                               p_oDict => p_oDict.ContainsKey(treeViewItemNames[0])
                                        && p_oDict.ContainsKey(treeViewItemNames[1])
                                        && p_oDict.ContainsKey(treeViewItemNames[2])
                                        && p_oDict.ContainsKey(treeViewItemNames[3])
                                        && p_oDict[treeViewItemNames[0]].Equals(continent)
                                        && p_oDict[treeViewItemNames[1]].Equals(country)
                                        && p_oDict[treeViewItemNames[2]].Equals(province)).Select(
                                        p_oDict => p_oDict[treeViewItemNames[3]])
                                        .Distinct()
                                        .ToList();
            Territories.Sort((p_oU1, p_oU2) => string.Compare(p_oU1.ToString(), p_oU2.ToString(), StringComparison.Ordinal));
            foreach (object territory in Territories)
            {
                var level4Items = new TreeViewContinents { Name = treeViewItemNames[3], Content = territory.ToString(), Parent = level3Items };
                level3Items.Children.Add(level4Items);
            }
        }
    }

    topItems.Add(level1Items);
}

在上面的代码中,我有四个foreach循环来构建树视图。是否有可能根据变量treeViewItemNames编写单个循环来生成treeView,以便将来如果我更改变量,如

var treeViewItemNames = new[] { "Continent", "Country", "Territory" };

它应该像这样生成treeView

+ Continent
    + Country
        + Territory

请提出意见/建议。

1 个答案:

答案 0 :(得分:1)

我建议迭代通过continentsList元素。

    var treeViewItemNames = new[] { "Continent", "Country", "Province", "Territory" };

     var topItems = new List<TreeViewContinents>();


     foreach (var continent in continentsList)
     {
         List<TreeViewContinents> currentLevel = topItems;
         TreeViewContinents parentItem = null;
         foreach (var sectionTitle in treeViewItemNames)
         {
             String value = Convert.ToString(continent[sectionTitle]);
             TreeViewContinents currentItem = currentLevel.FirstOrDefault(tree => tree.Content == value);
             if (currentItem == null)
             {
                 currentItem = new TreeViewContinents { Name = sectionTitle, Content = value };
                 currentItem.Children = new List<TreeViewContinents>();
                 if (parentItem != null)
                 {
                     currentItem.Parent = parentItem;
                 }
                 currentLevel.Add(currentItem);
             }
             parentItem = currentItem;
             currentLevel = currentItem.Children;
         }
     }

此代码的问题在于项目中没有排序,但我们可以对生成的TreeViewContinents列表进行排序。这是用于排序的递归方法:

public List<TreeViewContinents> SortTreeView(List<TreeViewContinents> treeViewList)
{
    foreach (var item in treeViewList)
    {
        if (item.Children.Count > 0)
        {
            item.Children = SortTreeView(item.Children);
        }
    }
    return treeViewList.OrderBy(it => it.Content).ToList();
}

您可以在topItems列表已满后使用它:

topItems = SortTreeView(topItems);