I want to show View Model on my UI using treeview, but I could not find a way to go more than one node deep The view should show the Persons and their Adress and their Adress details
using System.Collections.ObjectModel;
using System.ComponentModel;
public class Person : INotifyPropertyChanged
{
public string Name { get; set; }
public Address Address { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
public class Address : INotifyPropertyChanged
{
public string Street { get; set; }
public Postcode Postcode { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
public class Postcode : INotifyPropertyChanged
{
public string Code { get; set; }
public string Name { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
Tried nesting them inside each other with Datatemplates but no success
You can use the DataTemplateSelector for this. For example:
public partial class Person(string name, Address address) : ObservableObject
{
[ObservableProperty]
private string _name = name;
[ObservableProperty]
private Address _address = address;
}
public partial class Address(string street, Postcode postcode) : ObservableObject
{
[ObservableProperty]
private string _street = street;
[ObservableProperty]
private Postcode _postcode = postcode;
}
public partial class Postcode(string code, string name) : ObservableObject
{
[ObservableProperty]
private string _code = code;
[ObservableProperty]
private string _name = name;
}
public class TreeViewItemTemplateSelector : DataTemplateSelector
{
public DataTemplate PersonTemplate { get; set; } = new();
public DataTemplate AddressTemplate { get; set; } = new();
public DataTemplate PostcodeTemplate { get; set; } = new();
protected override DataTemplate SelectTemplateCore(object item)
{
return item switch
{
Person => PersonTemplate,
Address => AddressTemplate,
Postcode => PostcodeTemplate,
_ => base.SelectTemplateCore(item)
};
}
}
public class SingleItemToCollectionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
return new[] { value };
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
<Page.Resources>
<local:SingleItemToCollectionConverter x:Key="SingleItemToCollectionConverter" />
<local:TreeViewItemTemplateSelector x:Key="TreeViewItemTemplateSelector">
<local:TreeViewItemTemplateSelector.PersonTemplate>
<DataTemplate x:DataType="local:Person">
<TreeViewItem
Content="{x:Bind Name, Mode=OneWay}"
ItemsSource="{x:Bind Address, Mode=OneWay, Converter={StaticResource SingleItemToCollectionConverter}}" />
</DataTemplate>
</local:TreeViewItemTemplateSelector.PersonTemplate>
<local:TreeViewItemTemplateSelector.AddressTemplate>
<DataTemplate x:DataType="local:Address">
<TreeViewItem
Content="{x:Bind Street, Mode=OneWay}"
ItemsSource="{x:Bind Postcode, Mode=OneWay, Converter={StaticResource SingleItemToCollectionConverter}}" />
</DataTemplate>
</local:TreeViewItemTemplateSelector.AddressTemplate>
<local:TreeViewItemTemplateSelector.PostcodeTemplate>
<DataTemplate x:DataType="local:Postcode">
<TreeViewItem
Content="{x:Bind Name, Mode=OneWay}"
ItemsSource="{x:Bind Code, Mode=OneWay, Converter={StaticResource SingleItemToCollectionConverter}}" />
</DataTemplate>
</local:TreeViewItemTemplateSelector.PostcodeTemplate>
</local:TreeViewItemTemplateSelector>
</Page.Resources>
<TreeView
ItemTemplateSelector="{StaticResource TreeViewItemTemplateSelector}"
ItemsSource="{x:Bind ViewModel.People, Mode=OneWay}" />
ObservableObject and ObservableProperty come from the CommunityToolkit.Mvvm NuGet package.