Click here to Skip to main content
15,886,110 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have some data in my view-model, which looks roughly like this:
public class CostItem
{
	public string Description { get; set; }

	public int Quantity { get; set; }
	
	public double UnitCost { get; set; }
}


public class Section
{
	public string Name { get; set; }

	List<CostItem> CostItems { get; }
}


I am displaying it using the following TreeView:

C#
<TreeView x:Name="TreeViewBreakdown" ItemsSource="{Binding Sections}"
	AlternationCount="2">
	<TreeView.Resources>
		<HierarchicalDataTemplate DataType="{x:Type me:Section}" ItemsSource="{Binding CostItems}">
			<TextBlock Text="{Binding Name}"/>
		</HierarchicalDataTemplate>
		<DataTemplate DataType="{x:Type me:CostItem}">
			<Grid>
				<Grid.RowDefinitions>
					<RowDefinition Height="Auto"/>
				</Grid.RowDefinitions>
				<Grid.ColumnDefinitions>
					<ColumnDefinition/>
					<ColumnDefinition/>
					<ColumnDefinition/>
				</Grid.ColumnDefinitions>
				<TextBox Grid.Row="0" Grid.Column="0" Text="{Binding Description}"/>
				<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Quantity}"/>
				<TextBox Grid.Row="0" Grid.Column="2" Text="{Binding UnitCost}"/>
			</Grid>
		</DataTemplate>
	</TreeView.Resources>
</TreeView>

What I would like to do is apply and access an AlternationIndex to the CostItem child nodes displayed by this TreeView, so that I can alternate the background colour. Is there any way to do this?

Additional Note:
Having dug deeper into this, I think there is one central thing I am failing to grasp. I have declared two templates in my TreeView, one hierarchical and one normal, and these are chosen by type of object being bound to. All good so far.

In the case of the normal DataTemplate in my XAML, it is my understanding that this is the template applied to each child element. What I actually want to be able to say to the TreeView is something like, "When you are binding to my parent-class, I want you to use, say, a ListView or a DataGrid for all of the children of this parent." It is difficult to explain, but I'd be very grateful for clarification of this central point (if anyone understands what tosh I'm babbling on about)?

What I have tried:

It seems that what I need is this (taken from datagrid - How to make gridview a child element of a treeview in wpf application - Stack Overflow[^] ):

public class Customer
{
    public string Name { get; set; }
    public IEnumerable<Order> Orders { get; set; }
}

public class Order
{
    public DateTime PurchaseDate { get; set; }
    public IEnumerable<OrderItem> Items { get; set; }
}

public class OrderItem
{
    public string ProductName { get; set; }
    public int Quantity { get; set; }
    public double UnitPrice { get; set; }
    public double TotalPrice { get; set; }
}


<TreeView x:Name="_treeView" ItemsSource="{Binding}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type data:Customer}"
ItemsSource="{Binding Path=Orders}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type data:Order}">
<StackPanel>
<TextBlock Text="{Binding PurchaseDate}"/>
<ListView ItemsSource="{Binding Items}">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding ProductName}" />
<GridViewColumn DisplayMemberBinding="{Binding Quantity}" />
<GridViewColumn DisplayMemberBinding="{Binding UnitPrice}" />
<GridViewColumn DisplayMemberBinding="{Binding TotalPrice}" />
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>

Except what I need to do is chop off the top level of this tree (i.e. I don't need the Customer level. I get the feeling I'm being dense but I just don't seem to be able to work out the syntax to do this. Because I only have two levels, parent and child, do I even need a HierarchicalDataTemplate? Is that where I am going wrong?
Posted
Updated 17-Oct-19 2:05am
v4

Here is an example for a Listbox, but you probably can use the same technique for a TreeView: Custom WPF ListBox with Banding and Coloring in Code[^]

And here is a TreeView example: WPF 3.5 SP1 Feature: Alternating Rows – Vincent Sibal's Blog[^]

Although this example seems to be standard WPF, parts of it are using the PRISM framework: An Insight into Region Creation and RegionAdapters in Prism based WPF Applications[^]
 
Share this answer
 
v3
Comments
Patrick Skelton 17-Oct-19 4:07am    
Thank you for the reply. I will mark it as a solution but am delaying while I experiment because so far I haven't got it working. I'm struggling to see the difference between what I have and the example in the second link you gave, yet, when I look in the Live Visual Tree, I always get an AlternationIndex of 2, regardless of any changes I make to the AlternationCount in either the parent TreeView or its root HierarchicalDataTemplate. Any ideas what might be going wrong? (I'm puzzled that it is always 2; it is as if it is marking the items according to depth in the visual tree.)
Patrick Skelton 17-Oct-19 4:15am    
Modification to my previous comment to edit out brain-in-neutral bits: In the Live Visual Tree, I've been reading 'AlternationCount' as 'AlternationIndex'. is it possible to see the latter in the Live Visual Tree?
RickZeeland 17-Oct-19 5:38am    
The TreeView example appears to use the PRISM framework, sorry for that!
As my WPF Fu dates from years ago, I'm afraid I can not be of much help in this matter.
Using this example: https://www.dotnetperls.com/treeview-wpf[^]
I found that you can set the color of TreeView items in code behind like this:
TreeViewItem item = new TreeViewItem();
item.Header = "Computer";
item.Background = System.Windows.Media.Brushes.Yellow;

Another option might be using this open source custom control: MultiSelectTreeView control – unclassified software development[^]
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900