Apostrofix
Apostrofix

Reputation: 2180

How to populate a WPF multi column TreeView programmatically?

I am quite new to WPF and I spent the last few hours trying to add a TreeView which items contain multiple columns. I've looked on the internet for similar solutions, and I think that my problem is exactly the same, as explained in this answer: How to bind WPF TreeView to a List programmatically? However, it seems like I can't resolve it, so I thought to ask for help.

Here is the code that I have in XAML:

<TreeView Name="treeView1">
     <TreeView.ItemTemplate>
          <DataTemplate>
               <Grid>
                   <Grid.ColumnDefinitions>
                       <ColumnDefinition Width="Auto" />
                       <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding carModel}" />
                    <TextBlock Text="{Binding carHorsePower}" />
                </Grid>
          </DataTemplate>
      </TreeView.ItemTemplate>
</TreeView>

And this is the C# code behind:

CarDealer carDealer = GetDealerCars(); 

foreach(var groupedCar in carDealer.cars.GroupBy(x => x.carBrand).ToList())
{
    TreeViewItem item = new TreeViewItem();
    item.Header = groupedCar.Key; // This works fine, it shows the brands in the tree view
    item.ItemsSource = groupedCar; // This is not shown properly, because I am not sure how to bind the carModel and the carHorsePower properties from the list

    treeView1.Items.Add(item);
}

The CarDealer class looks like that:

public class CarDealer
{
    public string dealerAddress { get; set; }
    public List<Cars> cars { get; set;}
}

public class Cars
{
    public string carBrand { get; set; }
    public string carModel { get; set; }
    public string carHorsePower { get; set; }
}

For now, the tree view is shown, with the headers, but I am not sure how to add the multiple columns, and instead of the columns, now it just shows MyTestWpfApplication.Cars, as in the link above. I think I have to create text blocks and bind the data from my List<Cars> to them.

EDIT: What I am trying to achieve is something like that:

enter image description here

Upvotes: 1

Views: 3977

Answers (2)

Apostrofix
Apostrofix

Reputation: 2180

I wasn't able to find out how to do it and since I didn't have more time, I decided to go with a ListView and a GridView, which was actually easier to achieve.

To anyone else, who is trying to do the same, this is a good tutorial to start with: http://www.wpf-tutorial.com/listview-control/listview-grouping/

Upvotes: 1

tgpdyk
tgpdyk

Reputation: 1233

Modify your xaml:

<Window.Resources>
    <DataTemplate x:Key="subItems">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>
            <TextBlock Text="{Binding carModel}" />
            <TextBlock  Text="{Binding carHorsePower}" Margin="5, 0, 5, 0" Background="Bisque" Grid.Column="1"/>
        </Grid>
    </DataTemplate>
</Window.Resources>
<StackPanel>
    <TreeView Name="treeView1" Loaded="treeView1_Loaded">
    </TreeView>
</StackPanel>

Then modify your c# code:

 CarDealer carDealer = GetDealerCars();

 foreach (var groupedCar in carDealer.cars.GroupBy(x => x.carBrand).ToList())
 {
     TreeViewItem item = new TreeViewItem();
     item.Header = groupedCar.Key; 
     var src = new List<Cars>(groupedCar);
     item.ItemTemplate = (DataTemplate)FindResource("subItems");
     item.ItemsSource = src;

      treeView1.Items.Add(item);
 }

But then again, if you invest more time in converting your project in MVVM, with templates, etc.. this will be better.

Upvotes: 1

Related Questions