WPF Treeview with different collections for each depth - c#

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.

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?

How do I refer to a control in a WPF nested ListView?

My XAML:
<ListView x:Name="lvAlbums" ItemsSource="{Binding XPath=/downloads/Album}" SelectionMode="Multiple">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="spAlbum">
<!-- Displays first level attributes -->
<TextBlock x:Name="AlbumName" Text="{Binding XPath=#Name}"/>
<TextBlock x:Name="AlbumArtist" Text="{Binding XPath=#Artist}"/>
<ListView x:Name="lvTracks" ItemsSource="{Binding XPath=Item}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="spTrack">
<!-- Displays the second level attributes -->
<TextBlock x:Name="trackName" Text="{Binding XPath=#Name}"/>
<ProgressBar x:Name="pb1" Minimum="0" Maximum="100" Height="5px" Margin="0,0,0,0"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
It populates just fine from an xml file. I have an album and listed underneath are the tracks and a progress bar for each track.
I am now looping though the XML to download each track. How do I refer to the progressbar?
(ProgressBar)lvAlbums[curAlbum].lvTracks[curTrack].spTrack["pb1"]
Something like that.
Please see if this works for you :
var innerListView = lvAlbums.ItemTemplate.FindName("lvTracks", lvAlbums) as ListView;
ProgressBar pbar = innerListView.ItemTemplate.FindName("pb1", innerListView ) as ProgressBar;
Instead of trying to reference the progressbar control, I simply bound data to it and updated the data:
<ProgressBar x:Name="pb1" Value="{Binding XPath=#Progress, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Minimum="0" Maximum="100" Height="5px" Margin="0,0,0,0" Width="145"/>
Works as expected.

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.

TreeView doesn't have the AfterExpand event?

I try to have a treeview that browse potentially cyclic hierarchical data.
This means that I cannot try to load all the tree at once, since there maybe be infinite loops then.
I would like to react to the TreeView.AfterCollapse Event documented here at MSDN
however, my control doesnt seem to have this event. If I try to add the AfterExpand attribute, i get this error message:
error MC3072: The property 'AfterExpand' does not exist in XML namespace 'http://schemas.microsoft.com/winfx/2006/xaml/presentation'. Line 23 Position 21.
What I am doing wrong ? Calling a wrong namespace ?
Here is the code:
<Window x:Class="MyApp.Edit.EditView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyApp.Edit"
Title="{Binding WindowTitle,UpdateSourceTrigger=PropertyChanged}" MinHeight="350" MinWidth="350">
<Window.Resources>
<HierarchicalDataTemplate x:Key="sectionTemplate"
ItemsSource="{Binding ChildSections}"
DataType="{x:Type local:Section}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Label, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text=" - " />
<TextBlock Text="{Binding Description}" FontStyle="Italic" Foreground="#777" />
</StackPanel>
</HierarchicalDataTemplate>
</Window.Resources>
<StackPanel>
<TreeView ItemsSource="{Binding Sections}"
SelectedItemChanged="TreeView_SelectedItemChanged"
ItemTemplate="{StaticResource sectionTemplate}"
MinHeight="150"
MinWidth="300"
Name="treeView"
AfterExpand="MyEventHandler"
</TreeView>
<TextBox Text="{Binding Label, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0 10 0 0"/>
<TextBox Text="{Binding Description, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0 10 0 0"/>
<StackPanel Orientation="Horizontal">
<Button Content="Add Child" Click="Button_Click_AddChild" />
</StackPanel>
</StackPanel>
</Window>
That is a Windows Forms tree view event, it does not belong to the WPF TreeView, in WPF you can use Collapsed and Expanded of the TreeViewItems, not the TreeView itself.
However you can subscribe to the events on the TreeView as they are routed.

C1HierarchicalDataTemplate / C1TreeView Problem

I've a problem building up a ComponentOne TreeView in Silverlight (C1TreeView) with a C1HierarchicalDataTemplate. In detail the Tree only shows 2 levels (H1 and H2), although 3 levels are defined through HierarchicalDataTemplates like:
<c1:C1HierarchicalDataTemplate x:Key="H3Template">
<TextBlock FontWeight="Bold" Text="{Binding Path=Name}" />
</c1:C1HierarchicalDataTemplate>
<c1:C1HierarchicalDataTemplate x:Key="H2Template" ItemsSource="{Binding Path=H3Items}" ItemTemplate="{StaticResource H3Template}">
<TextBlock FontWeight="Bold" Text="{Binding Path=Name}" />
</c1:C1HierarchicalDataTemplate>
<c1:C1HierarchicalDataTemplate x:Key="H1Template" ItemsSource="{Binding Path=H2Items}" ItemTemplate="{StaticResource H2Template}">
<TextBlock FontWeight="Bold" Text="{Binding Path=Name}" />
</c1:C1HierarchicalDataTemplate>");
I'm using this Templates in a Custom TreeView (derived from C1TreeView):
<c1:C1TreeView ... ItemTemplate="{StaticResource H1Template}">
</c1:C1TreeView>
The constructor of this TreeView looks like this:
public MyTreeView(ObservableCollection<H1> h1Items)
{
InitializeComponent();
ItemsSource = h1Items;
}
Can anybody see the error in these code snippets??
thx, Dom
While I'm unfamiliar with the ComponentOne TreeView that you're using, and despite the fact that you are using Silverlight, normally in WPF when you are using HierarchicalDataTemplates, you tell the template what type it's for. Sub-item templates are similarly told what type they apply to. You don't specifically tell the data template what template to use for it's ItemTemplate. That is automatically figured out by the system based on the type of object. This also applies when you bind an item collection to the TreeView--you don't have to specify the ItemTemplate.
So in your case (local: is a namespace defined at the top of your xaml):
<c1:C1HierarchicalDataTemplate DataType="{x:Type local:H1}"
ItemsSource="{Binding Path=H2Items}">
<TextBlock FontWeight="Bold" Text="{Binding Path=Name}" />
</c1:C1HierarchicalDataTemplate>
<c1:C1HierarchicalDataTemplate DataType="{x:Type local:H2}"
ItemsSource="{Binding Path=H3Items}">
<TextBlock FontWeight="Bold" Text="{Binding Path=Name}" />
</c1:C1HierarchicalDataTemplate>
<c1:C1HierarchicalDataTemplate DataType="{x:Type local:H3}">
<TextBlock FontWeight="Bold" Text="{Binding Path=Name}" />
</c1:C1HierarchicalDataTemplate>
And the TreeView:
<c1:C1TreeView ItemsSource="{Binding SomeH1List}"/>
Of course, as I said, this applies to WPF, so it might not apply in your case.

Categories

Resources