C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

List型で入れ子になっているときのデータのセット方法

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■92924 / inTopicNo.1)  List型で入れ子になっているときのデータのセット方法
  
□投稿者/ 河童 (72回)-(2019/11/09(Sat) 15:57:33)

分類:[C#] 

いつも大変お世話になっております。

List型が入れ子になっているときリストにDataGridViewのデータをセットする方法を教えてください。
グループのリストにはチームのリストが入れ子になっています。
チームのリストにはユーザのリストが入れ子になっています。

DataGridViewのデータを取得して、
入れ子になっているチームとユーザのリストをどのように値を取得して
リストを完成させれば良いでしょうか?

大元はGroupLstです。この中にグループ、チーム、利用者の値を入れたいです。

わからないことは、
繰り返し処理を実行しているときに、一つの値しか取得できないので、
どの様にリストごとの値を取得すればいいかです。

ご教示よろしくお願いします。

        // グループリスト
        List<GroupInfo> GroupLst;
        public class GroupInfo
        {
            public int group_num { get; set; }     
            public string group_name { get; set; }
            public List<TeamInfo> teamList = new List<TeamInfo>(); 
        }
        // チームリスト
        public class TeamInfo
        {
            public int team_num { get; set; }
            public string team_name { get; set; }
            public List<UserInfo> userList = new List<UserInfo>(); 
        }
        // 利用者リスト
        public class UserInfo
        {     
            public int user_num { get; set; }          
            public string user_name { get; set; }       
        }
    
    // ロード時にデータをセット
        private void F01_Main_Load(object sender, EventArgs e)
        {
            // データを追加
            dgvGroup.Rows.Add(1, "GroupA", 1, "TeamA", 1, "User1");
            dgvGroup.Rows.Add(1, "GroupA", 1, "TeamA", 2, "User2");
            dgvGroup.Rows.Add(2, "GroupB", 2, "TeamB", 3, "User3");
            dgvGroup.Rows.Add(2, "GroupB", 2, "TeamB", 4, "User4");
            dgvGroup.Rows.Add(3, "GroupC", 3, "TeamC", 5, "User5");

        }

        // グループリストにセット
        private void btnApply_Click(object sender, EventArgs e)
        {
            GroupLst = new List<GroupInfo>();
            string check="";
            for (int i=0; i<4; i++)
            {
                for (int j=0; j<5; j++)
                {
                    GroupInfo d = new GroupInfo();
                    d.group_num = (int)dgvGroup.Rows[i].Cells[j].Value;

                    GroupLst.Add(d);

                    check += dgvGroup.Rows[i].Cells[j].Value;
                }
            }
        }

引用返信 編集キー/
■92925 / inTopicNo.2)  Re[1]: List型で入れ子になっているときのデータのセット方法
□投稿者/ 河童 (74回)-(2019/11/09(Sat) 17:43:56)
DataGridViewだと登録方法が難しいので、登録画面を再考します。
解決済み
引用返信 編集キー/
■92926 / inTopicNo.3)  Re[1]: List型で入れ子になっているときのデータのセット方法
□投稿者/ 魔界の仮面弁士 (2464回)-(2019/11/09(Sat) 17:49:40)
No92924 (河童 さん) に返信
> List型が入れ子になっているときリストにDataGridViewのデータをセットする方法を教えてください。

入れ子の List の内容を DataGridView にデータバインドして表示させるのではなく、
DataGridView の内容を入れ子の List に変換するのですね?


> for (int i = 0; i < 4; i++)
DataGridView には 5 行登録してあるようですが、
上記では先頭 3 行しか処理していないようですね。

全部の行では無く、先頭 n 行のみを処理したいのでしょうか?


> グループのリストにはチームのリストが入れ子になっています。
> チームのリストにはユーザのリストが入れ子になっています。

サンプルだと、一つのグループ内に一つのチームしか無いですね。

同じユーザーが複数のチームに所属したり、
同じチームが複数のグループに所属することはありますか?


> DataGridViewのデータを取得して、
> 入れ子になっているチームとユーザのリストをどのように値を取得して
> リストを完成させれば良いでしょうか?


private void btnApply_Click(object sender, EventArgs e)
{
    var users = dgvGroup.Rows.OfType<DataGridViewRow>().Where(row => !row.IsNewRow).Select(row => new
    {
        gInt = row.Cells[0].Value as int? ?? 0,
        gStr = row.Cells[1].Value as string ?? "",
        tInt = row.Cells[2].Value as int? ?? 0,
        tStr = row.Cells[3].Value as string ?? "",
        uInt = row.Cells[4].Value as int? ?? 0,
        uStr = row.Cells[5].Value as string ?? "",
    });

    var dicGroup = new Dictionary<int, GroupInfo>();
    var dicTeam = new Dictionary<int, TeamInfo>();
    foreach (var user in users)
    {
        GroupInfo g;
        TeamInfo t;
        if (!dicGroup.TryGetValue(user.tInt, out g))
        {
            dicGroup.Add(user.tInt, g = new GroupInfo { group_num = user.gInt, group_name = user.gStr, teamList = new List<TeamInfo>() });
        }
        if (!dicTeam.TryGetValue(user.tInt, out t))
        {
            g.teamList.Add(t = new TeamInfo { team_num = user.tInt, team_name = user.tStr, userList = new List<UserInfo>() });
            dicTeam.Add(user.tInt, t);
        }
        t.userList.Add(new UserInfo { user_num = user.uInt, user_name = user.uStr });
    }
    GroupLst = dicGroup.Values.ToList();
}

引用返信 編集キー/
■92929 / inTopicNo.4)  Re[2]: List型で入れ子になっているときのデータのセット方法
□投稿者/ 魔界の仮面弁士 (2466回)-(2019/11/09(Sat) 18:28:06)
回答をつける前に、方針転換による取り下げ行われていた…。 orz
解決済みマークを復活させるついでに追加投稿。


■No92925 (河童 さん) に返信
> DataGridViewだと登録方法が難しいので、登録画面を再考します。

階層の数だけ DataGridView を用意するという手もあります。使いやすいかどうかは仕様次第ですが。



空の DataGridView を 3 つと
BindingSource を 3 つ、
フォームに貼っておいてください。


private DataSet ds = new DataSet();
private void F01_Main_Load(object sender, EventArgs e)
{
    #region 型付DataSetを使えば、この部分をデザイン時に作成しておくこともできる
    var tblG = ds.Tables.Add("Group");
    tblG.Columns.Add("group_num", typeof(int));
    tblG.Columns.Add("group_name");
    tblG.PrimaryKey = new DataColumn[] { tblG.Columns["group_num"] };

    var tblT = ds.Tables.Add("Team");
    tblT.Columns.Add("group_num", typeof(int));
    tblT.Columns.Add("team_num", typeof(int));
    tblT.Columns.Add("team_name");
    tblT.PrimaryKey = new DataColumn[] { tblT.Columns["group_num"] , tblT.Columns["team_num"] };

    var tblU = ds.Tables.Add("User");
    tblU.Columns.Add("team_num", typeof(int));
    tblU.Columns.Add("user_num", typeof(int));
    tblU.Columns.Add("user_name");
    tblU.PrimaryKey = new DataColumn[] { tblU.Columns["team_num"], tblU.Columns["user_num"] };

    ds.Relations.Add("G_T", tblG.Columns["group_num"], tblT.Columns["group_num"]);
    ds.Relations.Add("T_U", tblT.Columns["team_num"], tblU.Columns["team_num"]);

    bindingSource1.DataSource = ds;
    bindingSource1.DataMember = "Group";
    bindingSource2.DataSource = bindingSource1;
    bindingSource2.DataMember = "G_T";
    bindingSource3.DataSource = bindingSource2;
    bindingSource3.DataMember = "T_U";

    dataGridView1.DataSource = bindingSource1;
    dataGridView2.DataSource = bindingSource2;
    dataGridView3.DataSource = bindingSource3;

    dataGridView2.Columns["group_num"].Visible = false;
    dataGridView3.Columns["team_num"].Visible = false;
    #endregion


    // データを追加
    ds.Tables["Group"].Rows.Add(1, "GroupA");
    ds.Tables["Group"].Rows.Add(2, "GroupB");
    ds.Tables["Group"].Rows.Add(3, "GroupC");
    ds.Tables["Team"].Rows.Add(1, 1, "TeamA");
    ds.Tables["Team"].Rows.Add(2, 2, "TeamB");
    ds.Tables["Team"].Rows.Add(3, 3, "TeamC");
    ds.Tables["User"].Rows.Add(1, 1, "User1");
    ds.Tables["User"].Rows.Add(1, 2, "User2");
    ds.Tables["User"].Rows.Add(2, 3, "User3");
    ds.Tables["User"].Rows.Add(2, 4, "User4");
    ds.Tables["User"].Rows.Add(3, 5, "User5");
    ds.AcceptChanges();

// dataGridView4.DataSource = ds.Tables["User"];
}


DataGridView の代わりに DataGrid を使えば、一つのコントロールで
階層構造を表現することもできます。
(.NET Framework 1.x 世代の設計なので扱いにくいですが)

解決済み
引用返信 編集キー/
■92930 / inTopicNo.5)  Re[3]: List型で入れ子になっているときのデータのセット方法
□投稿者/ 河童 (75回)-(2019/11/09(Sat) 19:26:54)
No92929 (魔界の仮面弁士 さん) に返信

ご回答ありがとうございます。
只今、画面を試行錯誤しています。
1つのDataGridViewでは難しそうなので、入れ子のリストごとにDataGridViewを作成しようと思っています。

各DataGridVieのソースはGroupLstを設定。

1つ目:dgvGroup
group_num
group_name
 
2つ目:dgvTeam
team_num
team_name

3つ目:dgvUser
user_num
user_name

あるグループを選択するとそれに連動したチームが表示される。
あるチームを選択するとそれに連動した利用者が表示さえるように設定を考えています。

連動させる方法がわからないので、新規に質問をさせていただきます。

引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ