none
DataTableのデータでTreeViewを構築する場合 RRS feed

  • 質問

  • DataTableのデータ

    ID SUB_ID VALUE
    1 1 root
    2 1 aaa
    3 2 bbb
    4 3 ccc
    5 1 ddd

    TreeViewのデータ

    ------------------------------------------------

    root
      aaa
        bbb
          ccc
      ddd

    ------------------------------------------------

    の様にできるプログラムを作りたいですが、アイディアが全然浮かびません。

    アドバイスを宜しくお願いします。

    -----------------------------Add -------------------------------------------------------

    親子関係がTreeviewで構築できるループ文を

    どう作ればいいのかを分かりません。

    宜しくお願いいたします。

     

     

     

    • 編集済み Pinokio-k 2010年11月30日 7:15
    2010年11月30日 6:24

回答

  • TreeNodeをHashで管理。

    SubIDを見て、そのハッシュからノードを取り出して子としてAdd.

    いったんトップに全部入れてから処理をしてもよいし、

    第1階層、第2階層を導きだして、その順に処理をしてもよい。

     

     

    • 回答としてマーク Pinokio-k 2010年11月30日 7:38
    2010年11月30日 7:12
  • 以下、R00tZer0さんで言うところの後者のやり方になります。

    こういったアイデアというかやり方を考えるのがプログラムの楽しい所だと思います。

    あくまで一例ですので、最終的にはご自身で、一番よい方法を考えてみてはいかがでしょう。

    // データテーブル
    DataTable dt = new DataTable();
    dt.Columns.Add("ID", typeof(int));
    dt.Columns.Add("SUB_ID", typeof(int));
    dt.Columns.Add("VALUE", typeof(string));
    dt.Rows.Add(new object[] { 2, 1, "aaa" });
    dt.Rows.Add(new object[] { 4, 3, "ccc" });
    dt.Rows.Add(new object[] { 1, 1, "root" });
    dt.Rows.Add(new object[] { 3, 2, "bbb" });
    dt.Rows.Add(new object[] { 5, 1, "ddd" });
    // IDで昇順にソート
    var sortedDt = from row in dt.AsEnumerable()
    			  orderby row.Field<int>("ID")
    			  select new
    			  {
    				  ID = row.Field<int>("ID"),
    				  SUB_ID = row.Field<int>("SUB_ID"),
    				  VALUE = row.Field<string>("VALUE")
    			  };
    // TreeViewに追加
    int nodeLevel = 1;
    this.treeView1.Nodes.Clear();
    TreeNodeCollection node = this.treeView1.Nodes;
    foreach (var row in sortedDt)
    {
    	if (nodeLevel > row.SUB_ID)
    	{
    		node = this.treeView1.Nodes;
    	}
    	else if (nodeLevel < row.SUB_ID)
    	{
    		node = node[node.Count - 1].Nodes;
    	}
    	nodeLevel = row.SUB_ID;
    	node.Add(row.VALUE);
    }
    
    

    • 回答としてマーク Pinokio-k 2010年11月30日 7:38
    2010年11月30日 7:21
  • とりあえずTreeViewへの追加の仕方はこの辺でどうでしょうか。
    http://www.atmarkit.co.jp/fdotnet/dotnettips/259treeviewadd/treeviewadd.html

    こんな感じでしょうか。

    DataTable dt = new DataTable();
    dt.Columns.Add("ID");
    dt.Columns.Add("SubID");
    dt.Columns.Add("Name");
    
    dt.Rows.Add(1, 1, "root");
    dt.Rows.Add(2, 1, "aaa");
    dt.Rows.Add(3, 2, "bbb");
    dt.Rows.Add(4, 3, "ccc");
    dt.Rows.Add(5, 1, "ddd");
    dt.Rows.Add(6, 1, "eee");
    
    treeView1.Nodes.Clear();
    
    Dictionary<int, TreeNode> nodeList = new Dictionary<int, TreeNode>();
    
    foreach (DataRow dr in dt.Rows)
    {
      // データ取得
      int id = Convert.ToInt32(dr["ID"]);
      int subid = Convert.ToInt32(dr["SubID"]);
      string name = dr["Name"].ToString();
    
      // ノード作成
      TreeNode node = new TreeNode(name);
      
      // ノード保管(なくてもできる気がする)
      nodeList.Add(id, node);
    
      if (id != subid)
      {
        // subidの設定があれば親を取得して子に追加
        TreeNode parent = nodeList[subid];
        parent.Nodes.Add(node);
      }
      else
      {
        // TreeViewに追加
        treeView1.Nodes.Add(node);
      }
    }
    

    • 回答としてマーク Pinokio-k 2010年11月30日 7:53
    2010年11月30日 7:35

すべての返信

  • TreeNodeをHashで管理。

    SubIDを見て、そのハッシュからノードを取り出して子としてAdd.

    いったんトップに全部入れてから処理をしてもよいし、

    第1階層、第2階層を導きだして、その順に処理をしてもよい。

     

     

    • 回答としてマーク Pinokio-k 2010年11月30日 7:38
    2010年11月30日 7:12
  • 以下、R00tZer0さんで言うところの後者のやり方になります。

    こういったアイデアというかやり方を考えるのがプログラムの楽しい所だと思います。

    あくまで一例ですので、最終的にはご自身で、一番よい方法を考えてみてはいかがでしょう。

    // データテーブル
    DataTable dt = new DataTable();
    dt.Columns.Add("ID", typeof(int));
    dt.Columns.Add("SUB_ID", typeof(int));
    dt.Columns.Add("VALUE", typeof(string));
    dt.Rows.Add(new object[] { 2, 1, "aaa" });
    dt.Rows.Add(new object[] { 4, 3, "ccc" });
    dt.Rows.Add(new object[] { 1, 1, "root" });
    dt.Rows.Add(new object[] { 3, 2, "bbb" });
    dt.Rows.Add(new object[] { 5, 1, "ddd" });
    // IDで昇順にソート
    var sortedDt = from row in dt.AsEnumerable()
    			  orderby row.Field<int>("ID")
    			  select new
    			  {
    				  ID = row.Field<int>("ID"),
    				  SUB_ID = row.Field<int>("SUB_ID"),
    				  VALUE = row.Field<string>("VALUE")
    			  };
    // TreeViewに追加
    int nodeLevel = 1;
    this.treeView1.Nodes.Clear();
    TreeNodeCollection node = this.treeView1.Nodes;
    foreach (var row in sortedDt)
    {
    	if (nodeLevel > row.SUB_ID)
    	{
    		node = this.treeView1.Nodes;
    	}
    	else if (nodeLevel < row.SUB_ID)
    	{
    		node = node[node.Count - 1].Nodes;
    	}
    	nodeLevel = row.SUB_ID;
    	node.Add(row.VALUE);
    }
    
    

    • 回答としてマーク Pinokio-k 2010年11月30日 7:38
    2010年11月30日 7:21
  • TreeNodeをHashで管理。

    SubIDを見て、そのハッシュからノードを取り出して子としてAdd.

    いったんトップに全部入れてから処理をしてもよいし、

    第1階層、第2階層を導きだして、その順に処理をしてもよい。

     

     

    DataTable folderDt= *** // データ取得
    TreeView tv = new TreeView();
    
    foreach (DataRow projectItem in folderDt.Rows)
    {
      if(projectItem["Value"].ToString().Equals("root"))
      {
         tv.Node.Add(projectItem.ToString());// TreeViewへNodeを追加
       }
      // この後の部分の階層的にすべてを入れる部分がわかりません。(><)。。。

    2010年11月30日 7:26
  • とりあえずTreeViewへの追加の仕方はこの辺でどうでしょうか。
    http://www.atmarkit.co.jp/fdotnet/dotnettips/259treeviewadd/treeviewadd.html

    こんな感じでしょうか。

    DataTable dt = new DataTable();
    dt.Columns.Add("ID");
    dt.Columns.Add("SubID");
    dt.Columns.Add("Name");
    
    dt.Rows.Add(1, 1, "root");
    dt.Rows.Add(2, 1, "aaa");
    dt.Rows.Add(3, 2, "bbb");
    dt.Rows.Add(4, 3, "ccc");
    dt.Rows.Add(5, 1, "ddd");
    dt.Rows.Add(6, 1, "eee");
    
    treeView1.Nodes.Clear();
    
    Dictionary<int, TreeNode> nodeList = new Dictionary<int, TreeNode>();
    
    foreach (DataRow dr in dt.Rows)
    {
      // データ取得
      int id = Convert.ToInt32(dr["ID"]);
      int subid = Convert.ToInt32(dr["SubID"]);
      string name = dr["Name"].ToString();
    
      // ノード作成
      TreeNode node = new TreeNode(name);
      
      // ノード保管(なくてもできる気がする)
      nodeList.Add(id, node);
    
      if (id != subid)
      {
        // subidの設定があれば親を取得して子に追加
        TreeNode parent = nodeList[subid];
        parent.Nodes.Add(node);
      }
      else
      {
        // TreeViewに追加
        treeView1.Nodes.Add(node);
      }
    }
    

    • 回答としてマーク Pinokio-k 2010年11月30日 7:53
    2010年11月30日 7:35
  • さっそくやってみます。

     

    ご返事どうもありがとうございます。

    2010年11月30日 7:38
  • ありがとうございます。

    すごく助かりました。

    2010年11月30日 7:50