How can I create a Hierarchical data template using tree view? - c#

I'm using a class created from entity frameworks (Categories table in database)
And only contains three fields:
CategoryID
CategoryName
ParentCategory
And entity framework created me two navigation: Subcategories and Parent
And when I load the collection in a treeview, it show me everything, where it should only show the top levels.
I think I should create a hierarquical data template, but I really have no idea about creating it.
EDIT: It similars these case: Entity Framework - Binding WPF Tree view control
My control XAML contains:
<TreeView x:Name="objectiveTree" ItemsSource="{Binding Objectives}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Subcategories}">
<TextBlock Text="{Binding Path=CategoryName}"
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>

You can try something like this:
Code-behind:
objectiveTree.ItemsSource = (List<YourMainEntity>) _entities;
XAML:
<TreeView x:Name="objectiveTree">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Subcategories}">
<TextBlock Text="{Binding ParentCategory}" />
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding CategoryName}"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>

<TreeView ItemsSource="{Binding YourItems}" ItemContainerStyle="
{StaticResource Level1}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}"
ItemContainerStyle="{StaticResource Level3}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>

Related

How to filter 3 level wpf treeview

Trying to filter level 2 and 3 nodes on a wpf treeview that is bound to a dataset.
I have tried using a value converter on the visibility property of the nodes but being a HierarchicalDataTemplate the converter isn't called.
<ObjectDataProvider x:Key="dataSetProvider" MethodName="GetDataSet" ObjectType="{x:Type local:DataSetCreator}"/>
<DataTemplate x:Key="SymbolTemplate">
<TextBlock Text="{Binding SymbolName}"/>
</DataTemplate>
<HierarchicalDataTemplate x:Key="FamilyTemplate" ItemsSource="{Binding Fam2Sym}" ItemTemplate="{StaticResource SymbolTemplate}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FamilyName}" />
<TextBlock><Run Text=" ("/><Run Text=")"/></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="Categorytemplate" ItemsSource="{Binding Cat2Fam}" ItemTemplate="{StaticResource FamilyTemplate}">
<TextBlock Text="{Binding LocalizedName}" />
</HierarchicalDataTemplate>
<TreeView x:Name="archTree" DataContext="{StaticResource dataSetProvider}" ItemsSource="{Binding RvtCat}"
ItemTemplate="{StaticResource Categorytemplate}"/>
I'm trying to filter a wpf treeview where if the level 2 OR 3 nodes match a string filter both levels are shown. I can't seem to find a way to do this. I've searched google but haven't found any similar questions. Suggestions?

WPF Treeview with different collections for each depth

i am completly new to WPF and need your help. I followed many tutorials but nothing works.
I have two ObserveableLists L1 and L2 to bind and I want to archiev:
On depth 1 - The first List and for each child list 2.
L1.1
L2.1
L2.2
L2.3
L1.2
L2.1
L2.2
L2.3
L1.3
L2.1
L2.2
L2.3
Update 16.02.07 - 16:44
My first try:
<TreeView Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="1" Margin="10" ItemsSource="{Binding orderCities}">
<TreeView.Resources>
<DataTemplate DataType="{x:Type model:city}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding name}" />
</StackPanel>
</DataTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding products}" DataType="{x:Type model:Product}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding name}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
My second try: Defining two DataTemplates how to handle my types:
<UserControl.Resources>
<HierarchicalDataTemplate DataType="{ x:TypeExtension model:city }" ItemsSource="{Binding orderCities}">
<StackPanel>
<TextBlock Text="{Binding name}" />
<!-- Here embed Product Type (Dont know how)-->
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{ x:TypeExtension model:Product }" ItemsSource="{Binding products}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding name}" />
<TextBlock Text=" - " />
<TextBox Text="1" />
</StackPanel>
</HierarchicalDataTemplate>
</UserControl.Resources>
And testet both templates and got the right design.
<TreeView ItemsSource="{Binding orderCities}" />
<TreeView ItemsSource="{Binding orderCities}" />
The treeview alone won't help you here. You have to actually create the data you want to display, i.e. the treeview won't "multiply" the two lists.
Each element in the first list may of course return the same instance of the second list in its children-property. You might want to have look at this codeproject article, it's rather old, but gives a nice introduction on how to use the wpf treeview.

How do I attached behaviors to a TreeViewItem?

I know how to attach behaviors to a TreeView, for example:
<TreeView
x:Name="TestCases"
ItemsSource="{Binding TestCases}"
Margin="0, 10, 0, 0">
<i:Interaction.Behaviors>
<behavior:TreeViewSelectedItemBlendBehavior />
</i:Interaction.Behaviors>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type testCases:TestCase}" ItemsSource="{Binding DataSets}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
But is it possible to add a behavior to every Item instead (to make something when "Selected" event is fired)? I don't know where I should put it as I use an ItemSource binding.

WPF - I'm stumped on the TreeView control

Pun intended.
I want to create a simple TreeView using the HierarchicalDataTemplate class.
Here's my problem XAML:
<Window.Resources>
<ObjectDataProvider
x:Key="myDataProvider"
ObjectType="vm:ContractViewModel" />
</Window.Resources>
<Window.DataContext>
<Binding Source="{StaticResource myDataProvider}" Path="Contract" />
</Window.DataContext>
<StackPanel
Orientation="Vertical"
VerticalAlignment="Top">
<ListBox MinWidth="400" Margin="10"
ItemsSource="{Binding Commissions}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Id}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TreeView>
<HierarchicalDataTemplate DataType="{x:Type m:Contract}"
ItemsSource="{Binding Commissions}">
<TextBlock Text="{Binding Id}" />
</HierarchicalDataTemplate>
</TreeView>
</StackPanel>
I'm using the MVVM pattern. The StaticResource "myDataProvider" returns an instance of a Contract (custom) class. Here's my model:
internal class Contract
{
public string Name { get; set; }
public ObservableCollection<Commission> Commissions { get; set; }
}
internal class Commission
{
public string Id { get; set; }
}
FYI - my model is actually more complex; my classes contain more members than shown, they have constructors, and they implement INotifyPropertyChanged.
In my test, I load two Commission objects into a Contract object. The listbox works as expected: I can see the Id of each Commission object w/in Contract. The TreeView doesn't work: it returns a "System.Windows.HierarchicalDataTemplate" string in the TreeView control where I'd expect each Commission Id to be listed.
I've referred to other posts and MSDN to no avail. I'd be appreciative of your help!
From what I can tell is that you're not using the TreeView correctly in XAML. You need to put your HierarchicalDataTemplate at the TreeView.Resources level and assign a ItemsSource
As shown here you want to set the Template of the item.
Try to do something like this instead:
<TreeView ItemsSource="{Binding Contracts}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type m:Contract}"
ItemsSource="{Binding Commissions}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type m:Commission}"
ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Id}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
I personally do it like this--using RadTreeView:
<telerik:RadTreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type vm:BaseType}"
ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Title}" />
</HierarchicalDataTemplate>
</telerik:RadTreeView.ItemTemplate>

Treeview not showing my children

I've not used the TreeView before other than in a few tutorials to get the hang of them. I thought I had, it turns out I haven't.
I'm trying to bind my TreeView to an object.
The Object is
public List<MyGrandparents> MyGrandParents {get;set;}
Within the MyGrandParent class, there is a property
public List<MyParents> MyParents{get;set;}
and lastly, within the MyParent class there is a property
public List<MyChildren> MyChildren {get;set;}
Within each class, there are other properties such as Name (no base classes though so no shared code at this stage)
I want to bind the lot to a tree view, so at 'root' level I only see grandparents. I can expand grandparents to only see parents, whom I can also expand to see children.
The issue I have is only the highest level is binding (grandparent level). My XAML is
<TreeView ItemsSource="{Binding MyGrandParents}">
<TreeView.Resources>
<DataTemplate DataType="{x:Type local:MyGrandParent}">
<TextBlock Text="{Binding Name}" Margin="0,0,10,0" />
</DataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:MyParent}" ItemsSource="{Binding MyGrandParents}">
<TextBlock Text="Don't bind to test"></TextBlock>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
I am lost as to why this isn't binding to give me a nice Tree.
You are not following correct pattern to use HierarchicalDataTemplate.
Item which might contain children should be declare as HierarchicalDataTemplate with ItemsSource set to child collection you want to show beneath it.
And item not containing any child should be declare as DataTemplate instead.
It should be like this -
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:MyGrandParent}"
ItemsSource="{Binding MyParents}">
<TextBlock Text="{Binding Name}" Margin="0,0,10,0" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:MyParent}"
ItemsSource="{Binding MyChildren}">
<TextBlock Text="Don't bind to test"></TextBlock>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:MyChildren}">
<TextBlock Text="Don't bind to test"></TextBlock>
</DataTemplate>
</TreeView.Resources>

Categories

Resources