C# - Ajuda com TreeView de 2 tabletas de MySQL, TableAdapter

Olá pessoas. Estou criando um programinha pra administrar licenças de softwares aqui no trabalho, e travei em uma parte.

Na tela inicial do programa eu quero uma TreeView listando os Softwares, e os nodes de cada software, suas versões.

Exemplo:

Adobe Photoshop

  • CS5
  • CS6

Depois disso o intúito é que quando eu clique duas vezes na versão, abra uma tabelinha das licenças que estão alocadas com este software e esta versão.

Consegui fazer listar os Softwares na TreeView, mas não sei como aplicar os nodes da tabela de versões, que é uma tabela a parte no MySQL que usa relacionamento a partir do ID dos Softwares:

Alguém pra dar uma ajudinha aí?

PS: Eu estava tentando entender como funcionava o TableAdapter, então utilizei isso pra popular a TreeView, mas deixei o código de como seria do jeito normal também.

Tabelas MySQL:

Código do Form:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MySql.Data.MySqlClient;

namespace OdinSWLManager
{
    public partial class Main : Form
    {

        public Main()
        {
            InitializeComponent();
        }

        private void Main_Shown(object sender, EventArgs e)
        {
            // ~*~*~* - Metódo 1 com Conexão e SQL Query no código. - *~*~*~ //
            /*
            string connString = "Server=D005m21832.metroweb.sp.gov.br;Port=3306;Database=odinswlmanager;Uid=Odin;password=odinsoftwaresgti123";
            MySqlConnection conn = new MySqlConnection(connString);
            try
            {
                conn.Open();

                string sql = "SELECT * FROM softwares";

                try
                {
                    DataSet ds = new DataSet();
                    MySqlDataAdapter msda = new MySqlDataAdapter(sql, conn);
                    DataTable dt = new DataTable();
                    msda.Fill(ds);

                    foreach (DataRow dr in ds.Tables[0].Rows)
                    {
                        TreeNode node = new TreeNode(dr["nome_sof"].ToString());
                        treeView.Nodes.Add(node);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Falha ao carregar os dados.", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Message", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            */

            // ~*~*~* - Metódo 2 com TableAdapter ( Método mais simples ). - *~*~*~ //
            try
            {
                AppDataTableAdapters.softwaresTableAdapter soft = new AppDataTableAdapters.softwaresTableAdapter();
                AppData.softwaresDataTable dt = soft.SoftwaresMain();
                soft.Fill(dt);

                foreach (DataRow dr in dt.Rows)
                {
                    TreeNode node = new TreeNode(dr["nome_sof"].ToString());

                    treeView.Nodes.Add(node);

                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Falha ao carregar os dados.", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }
    }
}

Acredito que na parte do TableAdapter vou ter que fazer algo assim para buscar os dados de versões também:

AppDataTableAdapters.softwaresTableAdapter soft = new AppDataTableAdapters.softwaresTableAdapter();
AppData.softwaresDataTable dt = soft.SoftwaresMain();
soft.Fill(dt);

AppDataTableAdapters.versoesTableAdapter vers = new AppDataTableAdapters.versoesTableAdapter();
AppData.versoesDataTable dt2 = vers.VersoesMain();
vers.Fill(dt2);

Mas daqui não sei mais como prosseguir, alguma ajuda?
Obrigado!!!

Quando um TreeNode é criado você pode passar o array dos filhos como parâmetro. Exemplo:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public class Software
    {
        public string Nome { get; set; }
        public IList<Versao> Versoes { get; set; }

        public Software()
        {
            Versoes = new List<Versao>();
        }
    }

    public class Versao
    {
        public string Nome { get; set; }
    }

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Simulando um software que viria do banco
            Software software = new Software();
            software.Nome = "Visual Studio";
            software.Versoes.Add(new Versao() { Nome = "2012" });
            software.Versoes.Add(new Versao() { Nome = "2013" });
            software.Versoes.Add(new Versao() { Nome = "2015" });

            AdicionarSoftwareComSuasVersoesNaTreeView(software);
        }

        private void AdicionarSoftwareComSuasVersoesNaTreeView(Software software)
        {
            TreeNode[] treeNodeArray = new TreeNode[software.Versoes.Count];

            for (int i = 0; i < software.Versoes.Count; i++)
            {
                treeNodeArray[i] = new TreeNode(software.Versoes[i].Nome);
            }

            var treeNode = new TreeNode(software.Nome, treeNodeArray);

            treeView1.Nodes.Add(treeNode);
        }
    }
}