ar.gorgin
ar.gorgin

Reputation: 5022

How to Fill TreeView from DataBase

I have a table(Hesab) whit 3 fields (ID,Name,FatherID), and use EF.

ID fatherID Name

1 NULL A

2 NULL B

3 2 C

4 1 D

5 4 E

6 4 F

7 3 G

8 1 H

and i want fill this table in treeview

the tree must be fill like this A -D --F --E -H B -C --G

I Created this class

   class Hesabs:Hesab
    {
    public Hesabs()
    {
        AllHesab = new ObservableCollection<Hesab>();
    }
    public ObservableCollection<Hesab> AllHesab { get; set; }
           }

and ViewModel

     public ObservableCollection<Hesabs> AllHesab { get; set; }
    public ObservableCollection<Hesabs> FirstHesab { get; set; }

    public ViewModelHesabs()
    { 
        CRMEntities crm=new CRMEntities();

        var ls = from h in crm.Hesab
                 where (h.FatherID == null)
                 select h;
        ObservableCollection<Hesabs> hes = new ObservableCollection<Hesabs>();
        foreach (Hesab hh in ls.ToList())
        {
            var ls2 = from h in crm.Hesab
                      where (h.FatherID == hh.ID)
                      select h;
            Hesabs hesab = new Hesabs();
            hesab.Name = hh.Name;
            hesab.ID = hh.ID;
            hesab.AllHesab = new ObservableCollection<Hesab>(ls2.ToList());
            hes.Add(hesab);
        }
        FirstHesab = hes;
    }

and xaml

        <TreeView ItemsSource="{Binding FirstHesab}">
        <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding AllHesab}" DataType="         {x:Type local:Hesabs}">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Name}"  Tag="{Binding ID}"/>
                </StackPanel>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

but fill 2 level :(

Upvotes: 0

Views: 475

Answers (1)

k.m
k.m

Reputation: 31464

You only check elements with FatherId == null and assigns their children - that's why you only get one level hierarchy in tree. Change:

foreach (Hesab hh in ls.ToList())

to:

foreach (Hesab hh in crm.Hesab.ToList())
{
    // ...
    // also assign father id, you'll need it to extract actual root elements
    hesab.FatherId = hh.FatherId;
}

To get root elements, simply query hes.Where(h => h.FatherId == null) and assign that to FirstHesab.

On a side note, your your view model could be better, instead of Hesabs class you could have:

class HesabViewModel
{
    HesabViewModel(Hesab hesab)
    {
        // set properties you'd like to expose to View, eg:
        this.Name = hesab.Name;
        this.Children = new ObservableCollection<HesabViewModel>();
    }

    public string Name { get; set; }
    public ObservableCollection<HesabViewModel> Children { get; private set; }
}

Basically, your view model classes should provide easier access to model objects for your views. Inheritance (like you do now), is probably not the best way - it doesn't really separate model from view.

Upvotes: 1

Related Questions