2009-05-16 8 views
2

いくつかのアイテム(もちろんparent-child1-child2 -... childNリレーション)でツリーのようなUIコントロールを作成する必要があります。先に進む前に、保持するマイコレクションC#ツリー/コレクションアルゴリズム

私のコレクション(注文されていないObservableCollection)の各オブジェクト(この場合はカテゴリクラスのインスタンス)は、パブリックプロパティ(文字列としてのParentCategoryID)を持ち、別の '私の木の中の親になる「カテゴリ」です。ツリー内のノードは、0個または任意の数の子を持つことができます。

ツリーを塗りつぶすときに、表示される各「カテゴリ」オブジェクトには、コレクション内の親カテゴリ(「親カテゴリ」に基づいて)がすでに設定されています。

ツリー内の要素を追加する前に、コレクションがこのように順序付けされていることを確認するために、どのアルゴリズムを使用する必要がありますか?

答えて

2

は私はわからないが、うまくいけば、それは助けになります。このため

using System; 
using System.Linq; 
using System.Collections; 
using System.Collections.Generic; 
public class Program 
{ 
    public static void Main(string[] args) 
    { 
     /* Tree Structure 

     a 
      d 
      e 
     b 
      f 
      i 
      j 
     c 
      g 
      h 
     */ 

     var a = new Category("a", null); 
     var b = new Category("b", null); 
     var c = new Category("c", null); 
     var d = new Category("d", "a"); 
     var e = new Category("e", "d"); 
     var f = new Category("f", "b"); 
     var g = new Category("g", "c"); 
     var h = new Category("h", "g"); 
     var i = new Category("i", "b"); 
     var j = new Category("j", "i"); 
     var k = new Category("k", "z"); 

     var list = new CategoryCollection { k, j, i, h, g, f, e, d, c, b, a }; 
     foreach (var category in list.SortForTree()) 
     { 
     Console.WriteLine("Name: {0}; Parent: {1}", category.Name, category.ParentCategoryID); 
     } 
    } 
} 

class Category 
{ 
    public string ParentCategoryID { get; set; } 
    public string Name { get; set; } 
    public Category(string name, string parentCategoryID) 
    { 
     Name = name; 
     ParentCategoryID = parentCategoryID; 
    } 
} 

class CategoryCollection : IEnumerable<Category> 
{ 
    private List<Category> list = new List<Category>(); 

    public void Add(Category category) 
    { 
     list.Add(category); 
    } 

    public IEnumerable<Category> SortForTree() 
    { 
     var target = new Dictionary<string, Category>(); 

     SortForTree(list, target); 

     return target.Values; 
    } 

    private void SortForTree(List<Category> source, Dictionary<string, Category> target) 
    { 
     var temp = new List<Category>(); 

     foreach (var c in source) 
     { 
     if (c.ParentCategoryID == null || (target.ContainsKey(c.ParentCategoryID) && !target.ContainsKey(c.Name))) 
     { 
      target.Add(c.Name, c); 
     } 
     else 
     { 
      if (source.Exists(o => o.Name == c.ParentCategoryID)) 
      { 
       temp.Add(c); 
      } 
     } 
     } 

     if (temp.Count > 0) SortForTree(temp, target); 
    } 

    #region IEnumerable<Category> Members 

    public IEnumerator<Category> GetEnumerator() 
    { 
     return list.GetEnumerator(); 
    } 

    #endregion 

    #region IEnumerable Members 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return list.GetEnumerator(); 
    } 

    #endregion 
} 
+1

感謝を。カテゴリの親を存在しないものに設定する場合を除いて、正常に動作しているようです。この場合、StackOverflow例外がスローされます。私はSortForTreeのforeachループでこのコードを使用しました(else brachでは)? if(source.Find(デリゲート(カテゴリo){return o.Name == c.ParentCategoryID;})!= null){temp.Add(c); }他に続ける....? –

+0

良いキャッチ。 StackOverflowを引き起こすStackOverflowにコードを投稿したことは面白いことです。あなたの修正をわずかに異なる方法で組み込むようにコードを更新しました。 – Robin

0

多分、子ノードは親ノードを知ってはいけません。私の意見では、その逆でなければなりません。各親ノードが子ノードの集合を保持し、この集合を新しいノードを追加した後にソートすることができる。多分これがあなたの問題を解決するでしょう。

よろしくお願いいたします。これはあなたが探しているものであれば