I'm struggling with how to refer/bind to the current item in a CollectionView's DataTemplate.
I've looked at questions like this, and thought I could apply the solution(s) to MAUI due to it and WPF both using XAML, but Intellisense complains that {Binding /} is not a valid binding path. Doing more digging revealed that I should use {Binding .}. So I tried that, however, trying to run my application results in it not even loading at all.
My xaml currently looks like this:
TreeNode.xaml
<maui:ReactiveContentView
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:maui="clr-namespace:ReactiveUI.Maui;assembly=ReactiveUI.Maui"
    xmlns:vm="clr-namespace:turquoise_frontend.Controls"
    xmlns:math="clr-namespace:HexInnovation;assembly=MathConverter.Maui"
    x:TypeArguments="vm:TreeNodeModel"
    x:DataType="vm:TreeNodeModel"
    x:Class="turquoise_frontend.Controls.TreeNode" x:Name="this">
    <VerticalStackLayout x:Name="sl2">
        <!-- stuff omitted due to being irrelevant here... -->
        <CollectionView ItemsSource="Children" x:Name="_ChildrenStackLayout" CanMixGroups="True" CanReorderItems="True" ReorderCompleted="_ChildrenStackLayout_ReorderCompleted">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <vm:TreeNode/>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </VerticalStackLayout>
</maui:ReactiveContentView>
I'm guessing the slowdown and the error is caused by the runtime interpreting {Binding .} to mean the object that the current xaml file represents as opposed to whatever the ItemTemplate is for, thus causing an infinite recursion.
So what am I supposed to write if I want to create a recursive layout that can take advantage of a CollectionView and also doesn't loop infinitely? Is what I'm trying to do even possible right now?
TreeNode.xaml.cs
    public partial class TreeNode : ReactiveContentView<TreeNodeModel>
    {
        public double? IndentWidth => Depth * SpacerWidth;
        public double? PaddingWidth => IndentWidth + 30;
        public int SpacerWidth { get; } = 40;
        private int? Depth => ViewModel?.Value.Depth ?? 0;
        public string ExpandText { get => (ViewModel?.Children?.Count ?? 0) > 0 ? "▷" : ""; }
        public TreeNode(TreeNodeModel tnm)
        {
            this.WhenAnyValue(x => x.ViewModel.isExpanded).ObserveOn(RxApp.MainThreadScheduler).Subscribe(b =>
            {
                _ChildrenStackLayout.IsVisible = b;
            });
            this.WhenAnyValue(b => b.ViewModel.selected).ObserveOn(RxApp.MainThreadScheduler).Subscribe(a =>
            {
                SelectionBoxView.IsVisible = a;
            });
            this.WhenAnyValue(b => b.ViewModel).ObserveOn(RxApp.MainThreadScheduler).WhereNotNull().Subscribe(vm =>
            {
                vm.Children.CollectionChanged += (o, e) =>
                            {
                                _SpacerBoxView.WidthRequest = IndentWidth ?? 0;
                            };
            });
            
            BindingContext = ViewModel = tnm;
            InitializeComponent();
        }
}
TreeNodeModel.cs
    public class TreeNodeModel : ReactiveObject
    {
        private ITreeNode _value;
        private ObservableCollection<TreeNodeModel> _children;
        private TreeNodeModel? _parent;
        private bool _toggled;
        private bool _selected;
        private bool _expanded;
        private string contract;
        [Reactive]
        public ITreeNode Value { get => _value; set => this.RaiseAndSetIfChanged(ref _value, value); }
        [Reactive]
        public TreeNodeModel? Parent
        {
            get => _parent; set
            {
                _parent = value;
                Value.Parent = value?.Value;
            }
        }
        [Reactive]
        public ObservableCollection<TreeNodeModel> Children
        {
            get
            {
                var nc = new ObservableCollection<TreeNodeModel>();
                foreach (var i in Value.Children ?? new ObservableCollection<ITreeNode>())
                {
                    var b = new TreeNodeModel(i, this.contract)
                    {
                        Tree = this.Tree
                    };
                    b.Parent = this;
                    nc.Add(b);
                }
                return nc;
            }
        }
        public TreeNodeModel Root
        {
            get
            {
                TreeNodeModel top = this;
                do
                {
                    if (top.Parent != null)
                        top = top.Parent;
                    else break;
                } while (top != null);
                return top ?? this;
            }
        }
        [Reactive]
        public bool isExpanded { get => _expanded; set => this.RaiseAndSetIfChanged(ref _expanded, value); }
        [Reactive] public bool Toggled { get => _toggled; set => this.RaiseAndSetIfChanged(ref _toggled, value); }
        public TreeModel Tree { get; set; }
        [Reactive]
        public bool selected { get => _selected; set => this.RaiseAndSetIfChanged(ref _selected, value); }
        public TreeNodeModel(ITreeNode val, string contract)
        {
            this.contract = contract;
            Toggled = val.Toggled;
            selected = false;
            isExpanded = false;
            
            _value = val;
            if (val.Parent != null)
                _parent = new TreeNodeModel(val.Parent, contract) { 
                    Tree = this.Tree
                };
            this.WhenAnyValue(b => b.Toggled).Subscribe(a =>
            {
                _value.Toggled = a;
            });
            this.WhenAnyValue(b => b.isExpanded);
            this.WhenAnyValue(b => b.Toggled);
            this.WhenAnyValue(b => b.selected);
        }
    }
ITreeNode interface
public interface ITreeNode
    {
        public object Value { get; set; }
        public ObservableCollection<ITreeNode> Children { get; }
        public ITreeNode? Parent { get; set; }
        public int Depth { get; }
        public int ID();
        public bool IsBranch { get; }
        public string AsString { get; }
        public bool Toggled { get; set; }
        public void Add(ITreeNode tn, int index);
        public void Add(ITreeNode tn);
        public void Remove(ITreeNode tn);
        public void Remove(int index);
        public bool Equals(ITreeNode other);
        public event NotifyCollectionChangedEventHandler NotifyCollectionChanged;
    }