I have one model named Visit
public class Visit
{
public int {get; set;}
public DateTime Date {get; set;}
public string VisitNo {get; set;}
public string Details {get;set;}
}
How can I populate a TreeView WinUI 3 like main roots are Years and Childrens are VisitNos.
I expecting the result below.
+2022
-0001
-0002
+2023
-0003
-0004
-0005
I guess this will do:
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace TreeViewExample;
public class Visit
{
public int Id { get; set; }
public DateTime Date { get; set; }
public string VisitNo { get; set; } = string.Empty;
public string Details { get; set; } = string.Empty;
}
public partial class YearItem : ObservableObject
{
public YearItem(int year)
{
Year = year;
}
[ObservableProperty]
private int year;
[ObservableProperty]
private ObservableCollection<Visit> visits = new();
}
public class TreeViewTemplateSelector : DataTemplateSelector
{
public DataTemplate? YearTemplate { get; set; }
public DataTemplate? VisitTemplate { get; set; }
protected override DataTemplate? SelectTemplateCore(object item)
{
return item switch
{
YearItem => YearTemplate,
Visit => VisitTemplate,
_ => throw new NotSupportedException(),
};
}
}
public partial class MainPageViewModel : ObservableObject
{
[ObservableProperty]
private ObservableCollection<YearItem> yearItems = new();
public MainPageViewModel()
{
List<Visit> visits = new()
{
new Visit { Id = 1, Date = DateTime.Now.AddYears(-1).AddMonths(-3), VisitNo = "001", Details = "Visit 1" },
new Visit { Id = 2, Date = DateTime.Now.AddYears(-1), VisitNo = "002", Details = "Visit 2" },
new Visit { Id = 3, Date = DateTime.Now.AddMonths(-2), VisitNo = "003", Details = "Visit 3" },
new Visit { Id = 4, Date = DateTime.Now.AddMonths(-1), VisitNo = "004", Details = "Visit 4" },
new Visit { Id = 5, Date = DateTime.Now, VisitNo = "005", Details = "Visit 5" }
};
foreach (Visit visit in visits)
{
if (YearItems
.Where(x => x.Year == visit.Date.Year)
.FirstOrDefault() is not YearItem visitsViewModel)
{
visitsViewModel = new(visit.Date.Year);
YearItems.Add(visitsViewModel);
}
visitsViewModel.Visits.Add(visit);
}
}
}
<Page
x:Class="TreeViewExample.MainPage"
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:local="using:TreeViewExample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Page.DataContext>
<local:MainPageViewModel x:Name="ViewModel" />
</Page.DataContext>
<Page.Resources>
<local:TreeViewTemplateSelector x:Key="TreeViewTemplateSelector">
<local:TreeViewTemplateSelector.YearTemplate>
<DataTemplate x:DataType="local:YearItem">
<TreeViewItem
Content="{x:Bind Year}"
ItemsSource="{x:Bind Visits}" />
</DataTemplate>
</local:TreeViewTemplateSelector.YearTemplate>
<local:TreeViewTemplateSelector.VisitTemplate>
<DataTemplate x:DataType="local:Visit">
<TextBlock Text="{x:Bind VisitNo}" />
</DataTemplate>
</local:TreeViewTemplateSelector.VisitTemplate>
</local:TreeViewTemplateSelector>
</Page.Resources>
<Grid>
<TreeView
ItemTemplateSelector="{StaticResource TreeViewTemplateSelector}"
ItemsSource="{x:Bind ViewModel.YearItems, Mode=OneWay}" />
</Grid>
</Page>