Given following model
class Storage
{
public List<Stored> StoredItems { get; }
}
class Stored
{
public string Name { get; set; }
public List<File> Files { get; } = new List<File>();
}
class File
{
public string Name { get; set; }
public Tree Schema { get; set; }
}
class Tree
{
public string Label { get; set; }
public List<Tree> Children { get; set; } = new List<Tree>();
}
I would like to display Storage in TreeView as follows:
StoredItem1.Name
File1.Schema.Label
File1.Schema.Children[0].Label
File1.Schema.Children[1].Label
File1.Schema.Children[1].Children.Label
File2.Schema.Label
StoredItem2.Name
i.e. display all Storeds that would contain Schema of each file, which is recursive.
I am not sure how to achieve it, my main problem is how to get the Schema to be displayed. When I changed my model to wrap Schema in a singleton list, it started to work but I would like to avoid polluting my model with such thing, also still, I don't want to display file name and instead of file display its schema.
Another thing I would like to have have a property SelectedStoredItem in my view model and bind it to, well, selected Stored item. It can be null if for example some schema node is selected, or be equal to the Stored to which selected node belongs, but I prefer first option.
Here is my xaml, it doesn't do what I want, just displays Stored items and their file names.
<Window x:Class="TreeViewTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TreeViewTest"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:Storage/>
</Window.DataContext>
<Grid>
<TreeView
ItemsSource="{Binding StoredItems}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:Stored}"
ItemsSource="{Binding Files}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:File}"
ItemsSource="{Binding Schema}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Tree}"
ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Label}"/>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</Window>
and here is complete code behind
namespace TreeViewTest
{
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
}
class Storage
{
public Storage()
{
StoredItems = new List<Stored>();
var a1 = new Stored {Name = "Stored1"};
a1.Files.Add(new File
{
Name = "File1",
Schema = new Tree
{
Label = "1_1",
Children = new List<Tree> { new Tree { Label = "1_1_1" } }
}
});
a1.Files.Add(new File
{
Name = "File2",
Schema = new Tree
{
Label = "2_1",
Children = new List<Tree> { new Tree { Label = "2_1_1" }, new Tree { Label = "2_1_2" } }
}
});
var a2 = new Stored { Name = "Stored2" };
a2.Files.Add(new File
{
Name = "File1",
Schema = new Tree
{
Label = "1_1",
Children = new List<Tree> { new Tree { Label = "1_1_1" } }
}
});
StoredItems.Add(a1);
StoredItems.Add(a2);
}
public List<Stored> StoredItems { get; }
}
class Stored
{
public string Name { get; set; }
public List<File> Files { get; } = new List<File>();
}
class File
{
public string Name { get; set; }
public Tree Schema { get; set; }
}
class Tree
{
public string Label { get; set; }
public List<Tree> Children { get; set; } = new List<Tree>();
}
}