I've the following TreeView:
<Grid>
<TreeView Background="LightGoldenrodYellow" Grid.Row="3">
<TreeViewItem Header="Section 4">
<TreeViewItem>
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Total:" Width="150"/>
<TextBlock Text="{Binding Pool.Count}" />
</StackPanel>
</TreeViewItem.Header>
</TreeViewItem>
<TreeViewItem>
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Code" Width="150" />
<TextBlock Text="{Binding SecretViewModel.Codes}" />
</StackPanel>
</TreeViewItem.Header>
</TreeViewItem>
<TreeViewItem Header="Sub-Section 4.1">
<TreeViewItem>
<ListBox ItemsSource="{Binding Path=ListOfNames, UpdateSourceTrigger=PropertyChanged}" />
</TreeViewItem>
</TreeViewItem>
</TreeViewItem>
<TreeViewItem Header="Section 5">
<TreeViewItem>
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Color:" Width="150" />
<TextBlock Text="{Binding Colors}" />
</StackPanel>
</TreeViewItem.Header>
</TreeViewItem>
</TreeView>
</Grid>
How can I replace the Listbox and can bind the ObservableCollection to the TreeviewItem? It should look hierarchical.
I've tried to insert this code instead of the with the TextBox, but that does not work:
<HierarchicalDataTemplate>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=ListOfNames, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
Not quite sure what exactly you are trying to achieve. You don't mean...
<TreeViewItem Header="Section 4">
<TreeViewItem Header="Sub-Section 4.1"
ItemsSource="{Binding Path=ListOfNames,
UpdateSourceTrigger=PropertyChanged}" />
</TreeViewItem>
Related
I have tree view in wpf, it looks like:
CategoryName1
Image1 ChildElementName1
Image2 ChildElementName2
Image3 ChildElementName3
CategoryName2
Image1 ChildElementName1
Image2 ChildElementName2
Image3 ChildElementName3
...
How i can use in my CategoryNames image from child[0]? I tried binding on element name, but this is not working.
My xaml code is:
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=Items}">
<StackPanel Orientation="Horizontal">
<Image Source="here i dont know how to do properly"/>
<TextBlock Text="{Binding Path=Name}"/>
</StackPanel>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image x:Name="img"
Source="{Binding Path=ImageSource}"/>
<TextBlock Text="{Binding Path=Name}"/>
</StackPanel>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
The solution is simple, but i dont know how correct it is
We can refer like this
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=Items}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Path=Items[0].ImageSource}"/>
<TextBlock Text="{Binding Path=Name}"/>
</StackPanel>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image x:Name="img"
Source="{Binding Path=ImageSource}"/>
<TextBlock Text="{Binding Path=Name}"/>
</StackPanel>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
how can i do that...
Field
--Crop year <-- property of crop. I want here an extra level for sorting like 2017 or 2018
---Crop
----Fertilizer
----Pesticide
... if "Crop year" is a datetime in crop. How can i get the extra level "year"?
<TreeView x:Name="tvFields" Margin="10" HorizontalContentAlignment="Stretch">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type entites:Field}" ItemsSource="{Binding Items}">
<StackPanel Orientation="Horizontal" Background="LightGreen">
<TextBlock Text="{Binding Name}" FontSize="16"/>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type entites:Crop}" ItemsSource="{Binding PestItems}">
<StackPanel Orientation="Horizontal" Background="LightBlue">
<TextBlock Text="{Binding Name}" FontSize="14" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type entites:Pesticide}" ItemsSource="{Binding PestItems}">
<StackPanel Orientation="Horizontal" Background="PaleGreen">
<TextBlock Text="{Binding Name}" FontSize="14" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type entites:Fertilizer}" ItemsSource="{Binding FertItems}">
<StackPanel Orientation="Horizontal" Background="Beige">
<TextBlock Text="{Binding Name}" FontSize="14" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
Should I create an extra class for "Crop year"?
Lyror
Basically i have a eeview that has a bunch of objects in it and the treeview needs to bind the same properties.
here is the code im using and it doesnt seem to work
<TreeView ItemsSource="{Binding Drives}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate>
<TreeViewItem Header="{Binding Name}" ItemsSource="{Binding Folders}" IsExpanded="{Binding IsExpanded, Mode=TwoWay}">
<TreeViewItem.ItemTemplate>
<HierarchicalDataTemplate>
<StackPanel>
<TreeViewItem Header="{Binding Name}" ItemsSource="{Binding Folders}" IsExpanded="{Binding IsExpanded,Mode=TwoWay}">
<TreeViewItem.ItemTemplate>
<HierarchicalDataTemplate>
<TreeViewItem Header="{Binding Name}" ItemsSource="{Binding Folders}" IsExpanded="{Binding IsExpanded,Mode=TwoWay}"/>
</HierarchicalDataTemplate>
</TreeViewItem.ItemTemplate>
</TreeViewItem>
</StackPanel>
</HierarchicalDataTemplate>
</TreeViewItem.ItemTemplate>
</TreeViewItem>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Basically when i get to the third level of treeview items i just get the Namespace+ObjectName.
Isnt the DataTemplate supposed to flow on and on ?
More like this
<TreeView ItemsSource="{Binding Drives}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Folders}">
<TextBlock Text="{Binding Name}"></TextBlock>
<HierarchicalDataTemplate.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding IsExpanded,Mode=TwoWay}" />
</Style>
</HierarchicalDataTemplate.ItemContainerStyle>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
I would like to have previous/next arrows to select items in the treeview. I have 3 parent nodes that have childs. The parent nodes won't do anything so if I was at the end of the childs in parent node 1, I want the next arrow to select the 1st child in parent node 1. Same with the reverse if on the fist node of parent 2 and clicking previous will take me to the last child or parent node 1.
xaml of the treeview currently
<TreeView x:Name="tvMessages" HorizontalAlignment="Left" Height="363" Margin="10,37,0,0" VerticalAlignment="Top" Width="312" SelectedItemChanged="tvMessages_SelectedItemChanged">
<TreeViewItem x:Name="itemsCritical">
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="/FlashSystem/Images/Critical.png" Height="16px" Width="16px"/>
<TextBlock Margin="5,0" Text="Critical"/>
</StackPanel>
</TreeViewItem.Header>
<TreeViewItem.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="/FlashSystem/Images/Message.png" Width="16px" Height="16px"/>
<TextBlock Margin="5,0" Text="{Binding Description}"/>
<TextBlock Text="{Binding ID}" Visibility="Hidden"/>
<TextBlock Text="{Binding Specility}" Visibility="Hidden"/>
<TextBlock Text="{Binding IssuedDate}" Visibility="Hidden"/>
<TextBlock Text="{Binding Severity}" Visibility="Hidden"/>
</StackPanel>
</DataTemplate>
</TreeViewItem.ItemTemplate>
</TreeViewItem>
<TreeViewItem x:Name="itemsAlert">
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="/FlashSystem/Images/Alert.png" Height="16px" Width="16px"/>
<TextBlock Margin="5,0" Text="Alert"/>
</StackPanel>
</TreeViewItem.Header>
<TreeViewItem.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="/FlashSystem/Images/Message.png" Width="16px" Height="16px"/>
<TextBlock Margin="5,0" Text="{Binding Description}"/>
<TextBlock Text="{Binding ID}" Visibility="Hidden"/>
<TextBlock Text="{Binding Specility}" Visibility="Hidden"/>
<TextBlock Text="{Binding IssuedDate}" Visibility="Hidden"/>
<TextBlock Text="{Binding Severity}" Visibility="Hidden"/>
</StackPanel>
</DataTemplate>
</TreeViewItem.ItemTemplate>
</TreeViewItem>
<TreeViewItem x:Name="itemsInformational">
<TreeViewItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="/FlashSystem/Images/Info.png" Height="16px" Width="16px"/>
<TextBlock Margin="5,0" Text="Informational"/>
</StackPanel>
</TreeViewItem.Header>
<TreeViewItem.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="/FlashSystem/Images/Message.png" Width="16px" Height="16px"/>
<TextBlock Margin="5,0" Text="{Binding Description}"/>
<TextBlock Text="{Binding ID}" Visibility="Hidden"/>
<TextBlock Text="{Binding Specility}" Visibility="Hidden"/>
<TextBlock Text="{Binding IssuedDate}" Visibility="Hidden"/>
<TextBlock Text="{Binding Severity}" Visibility="Hidden"/>
</StackPanel>
</DataTemplate>
</TreeViewItem.ItemTemplate>
</TreeViewItem>
</TreeView>
I would try to simulate the key down event and see if it works.
If you simulate the arrow key down event the TreeViewItem will do the job for you. It will either expand itself or move the selection to its Children[0] item.
Internally TreeViewItem listens to KeyDown and it works with ItemContainerGenerator to find the Children[0] item.
Here is how you can simulate arrow key in WPF:
var backKey = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, Key.Back);
backKey.RoutedEvent = Keyboard.KeyDownEvent;
InputManager.Current.ProcessInput(backKey);
You wont need the back key you will need the right or left arrow still you will need InputManager to process input :)
I have built a WPF MVVM TreeView that shows different Elements.
BaseElement
- CatA
-- SubItemA
- CatB
-- SubItemB
Based on the class I would like to use a different data template.
for each type.
So far I can connect to the selected Item, but I'm not sure how to manage the different data templates.
public class SubItem
{
public string Type { get; set; }
public string Name { get; set; }
}
<StackPanel Grid.Column="2" DataContext="{Binding ElementName=myTreeView, Path=SelectedItem}">
<TextBox Text="{Binding Parent.Name}" />
<TextBox Text="{Binding Path=Name, Mode=TwoWay}" />
</StackPanel>
[Update Nov. 15]
<HierarchicalDataTemplate x:Key="L3Template" ItemsSource="{Binding L4Collection}" ItemTemplate="{StaticResource L4Template}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="CategoryTemplate" ItemsSource="{Binding L3Collection}" ItemTemplate="{StaticResource L3Template}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="L1Template" ItemsSource="{Binding CategoryCollection}" ItemTemplate="{StaticResource CategoryTemplate}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
[/Update Nov. 15]
If the subitems are different classes, then it is rather simple: add datatemplates foreach class to the resource section.
If subitems need different templates based on the value of an enum prop, then you will need a datatemplateselector. This is a bit more cumbersome.
Assuming that you named your classes L1Class, L3Class en Category and local points to the namespace of these classes:
<TreeView ...>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:L3Class}" ItemsSource="{Binding L4Collection}" >
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Category}" ItemsSource="{Binding L3Collection}" >
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:L1Class}" ItemsSource="{Binding CategoryCollection}" >
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
Note the use of the implicit datatemplates (no keys, but DataType!) in the resource section.
Just in case it will help someone else:
<ContentPresenter Grid.Column="2" Content="{Binding ElementName=myTreeView, Path=SelectedItem}">
<ContentPresenter.Resources>
<DataTemplate DataType="{x:Type local:L1ViewModel}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:CategoryViewModel}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:L3ViewModel}">
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:L4ViewModel}">
<StackPanel>
<TextBox Text="{Binding Parent.Name}" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ContentPresenter.Resources>
</ContentPresenter>