0

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

1 Answer 1

0

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.