Multiple level TreeView
<p>My goal is to create TreeView like that :</p>

<pre><code> alias1
 --TABLES  ( constant string ) 
 ----TABLE_NAME11
 ----TABLE_NAME12 
 ----TABLE_NAME13
 ---- ...
 --INDEXES  ( constant string ) 
 ----INDEX_NAME11
 ----INDEX_NAME12
 ---- ...
alias2
--TABLES ( constant string ) 
----TABLE_NAME21
----TABLE_NAME22 
----TABLE_NAME23
---- ...
--INDEXES  ( constant string ) 
----INDEX_NAME21
----INDEX_NAME22
.... (n)
alias(n)
++TABLES  ( constant string ) 
++INDEXES ( constant string ) 
</code></pre>

<p>I think i had read every topic on stackoverflow about TreeView, HierarhicalDataTemplate but I can't make structure similar to this.</p>

<p>I try to adjust every topic to my viewmodel but I really can't.</p>

<p>So I think I should do that step by step.</p>

<ol>
<li>Bind aliases as TreeViewItem (DONE).</li>
<li>Expand aliases to constant strings 'TABLES' and 'INDEXES'.</li>
</ol>

<p>My structure looks always like this:</p>

<pre><code> alias1   
 alias2 
 alias3 
 alias4
</code></pre>

<p>It have not any button to expand aliases. 
It is only list of aliases.          </p>

<p><strong>My whole XML:</strong>
            </p>

<pre><code>    &lt;Grid&gt;
        &lt;TabControl&gt;
            &lt;TabItem Header="Map"&gt;Mapa&lt;/TabItem&gt;
            &lt;TabItem Header="History"&gt;History&lt;/TabItem&gt;
            &lt;TabItem Header="Aliases"&gt;
            &lt;Grid&gt;
                &lt;TreeView Name="AliasesTree" ItemsSource="{Binding aliases}"&gt;
                    &lt;TreeView.ItemContainerStyle&gt;
                        &lt;Style TargetType="{x:Type TreeViewItem}"&gt;
                            &lt;Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" /&gt;
                            &lt;Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" /&gt;
                            &lt;Setter Property="FontWeight" Value="Normal" /&gt;
                            &lt;Style.Triggers&gt;
                                &lt;Trigger Property="IsSelected" Value="True"&gt;
                                    &lt;Setter Property="FontWeight" Value="Bold" /&gt;
                                &lt;/Trigger&gt;
                            &lt;/Style.Triggers&gt;
                        &lt;/Style&gt;
                    &lt;/TreeView.ItemContainerStyle&gt;

                    &lt;TreeView.Resources&gt;
                        &lt;HierarchicalDataTemplate DataType="{x:Type models:ConnectionModel }" 
                                                  ItemsSource="{Binding aliases}"
                        &gt;
                            &lt;StackPanel Orientation="Horizontal"&gt;
                                &lt;TextBlock Text="{Binding alias}" /&gt;
                            &lt;/StackPanel&gt;
                        &lt;/HierarchicalDataTemplate&gt;

                        &lt;HierarchicalDataTemplate DataType="string"&gt;
                            &lt;StackPanel Orientation="Horizontal"&gt;
                                &lt;TextBlock Text="TABLES" /&gt;
                                &lt;TextBlock Text="INDEXES" /&gt;
                            &lt;/StackPanel&gt;
                        &lt;/HierarchicalDataTemplate&gt;
                    &lt;/TreeView.Resources&gt;
                &lt;/TreeView&gt;
            &lt;/Grid&gt;
            &lt;/TabItem&gt;
        &lt;/TabControl&gt;
    &lt;/Grid&gt;
</code></pre>

<p><strong>My page.cs file :</strong></p>

<pre><code>      public partial class SideBar : Page
{
    public List&lt;ConnectionModel&gt; aliases = ConnectionUtilities.LoadConnections();

    public SideBar()
    {
        InitializeComponent();

        LoadSideBar();

        DataContext = new { aliases = this.aliases , this.DataContext  };

        // AliasesTree.ItemsSource = aliases;

    }

    public async Task LoadSideBar()
    {
        await LoadAliasTreeView();
    }


    public async Task LoadAliasTreeView()
    {

        //aliasTreeView.ItemsSource = ConnectionUtilities.LoadConnections();
        OdbcDataAdapter MainOdbcAdapter = new OdbcDataAdapter();
        String commandString = "";

        foreach (ConnectionModel connection in aliases)
        {
            await Dispatcher.InvokeAsync(
                async () =&gt;
                {
                    using (OdbcConnection con = new OdbcConnection("DSN=" + connection.dsn.ToString()
                                                                + ";UID=" + connection.username.ToString()
                                                                + ";PWD=" + connection.password.ToString()))
                    {
                        using (MainOdbcAdapter = new OdbcDataAdapter(commandString, con))
                        {
                            if (con.State == ConnectionState.Closed)
                                con.Open();
                            await Task.Run(() =&gt;
                            {
                                using (DataTable tableschema = con.GetSchema("TABLES"))
                                {
                                    // first column name
                                    foreach (DataRow row in tableschema.Rows)
                                    {
                                        connection.tables.Add(new TableModel() { TABLE_NAME = row["TABLE_NAME"].ToString() });
                                        //  MessageBox.Show(  row["TABLE_NAME"].ToString()); Sprawdzone, dziala, pokazuje nazwy tabel
                                    }
                                }
                            });
                        }
                    }
                });

        }

        //aliasTreeView.ItemsSource = aliases;

    }
</code></pre>

<p><strong>My models</strong></p>

<pre><code> namespace ProgDB4.Model
 {
[Serializable()]
public class ConnectionModel
{

    private int    _id;

    private string _dsn;
    private string _alias   ;

    private string _host    ;
    private string _port    ;

    private string _database;

    private string _username;
    private string _password;

    public List&lt;TableModel&gt; tables  = new List&lt;TableModel&gt;(); 
    public List&lt;IndexModel&gt; indexes = new List&lt;IndexModel&gt;();

    [System.Xml.Serialization.XmlElement("id")]
    public int id
    {
        get { return _id; }
        set { if (value != _id) _id = value; }
    }

    [System.Xml.Serialization.XmlElement("dsn")]
    public string dsn
    {
        get { return _dsn; }
        set { if (value != _dsn) _dsn = value; }
    }

    [System.Xml.Serialization.XmlElement("alias")]
    public string alias
    {
        get { return _alias; }
        set { if (value != _alias) _alias = value; }
    }

    [System.Xml.Serialization.XmlElement("host")]
    public string host
    {
        get { return _host; } 
        set { if (value != _host) _host = value; }
    }

    [System.Xml.Serialization.XmlElement("port")]
    public string port
    {
        get { return _port; }
        set { if (value != _port) _port = value; }
    }

    [System.Xml.Serialization.XmlElement("username")]
    public string username
    {
        get { return _username; }
        set { if (value != _username) _username = value; }
    }

    [System.Xml.Serialization.XmlElement("password")]
    public string password
    {
        get { return _password; }
        set { if (value != _password) _password = value; }
    }

    [System.Xml.Serialization.XmlElement("database")]
    public string database
    {
        get { return _database; }
        set { if (value != _database) _database = value; }
    }

    public ConnectionModel()
    {
        _id = 1;
        _dsn    = "";
        _alias  = "New Conn";

        _host = "http://192.168.0.1";
        _port = "22";

        _database = "database_name";

        _username = "login";
        _password = "pass";
    }

    public ConnectionModel( int newItemId )
    {
        _id = newItemId;
        _dsn    = "";
        _alias  = "New Conn";

        _host = "http://192.168.0.1";
        _port = "22";

        _database = "database_name";

        _username = "login";
        _password = "pass" ;
    }


}


public class TableModel
{
    public string TABLE_CAT     { get; set; }  = "";
    public string TABLE_SCHEM   { get; set; }  = "";
    public string TABLE_NAME    { get; set; }  = "";
    public string TABLE_TYPE    { get; set; }  = "";
    public string REMARKS       { get; set; } = "";
}

public class IndexModel
{                                  
    public string TABLE_CAT        { get; set; }  = "";
    public string TABLE_SCHEM      { get; set; }  = "";
    public string TABLE_NAME       { get; set; }  = "";
    public int    NON_UNIQUE       { get; set; }  = 0 ;
    public string INDEX_QUALIFIER  { get; set; }  = "";
    public string INDEX_NAME       { get; set; }  = "";
    public int    TYPE             { get; set; }  = 0 ;
    public int    ORDINAL_POSITION { get; set; }  = 0 ;
    public string COLUMN_NAME      { get; set; }  = "";
    public string ASC_OR_DESC      { get; set; }  = "";
    public int    CARDINALITY      { get; set; }  = 0 ;
    public int    PAGES            { get; set; }  = 0 ;
    public string FILTER_CONDITION { get; set; }  = "";

}


}
</code></pre>

<p>Thank You for any advise.</p>

<p>My next steps will be:
3. Expand "TABLES" to List  of table names in TableModel.TABLE_NAME.</p>