📄 OutGridTree.Window/MainWindow.axaml.cs
using System;
using System.Collections.ObjectModel;
using System.Management.Automation;
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Data.Converters;

namespace OutGridTree.Window;

internal sealed partial class MainWindow : Avalonia.Controls.Window
{
    private readonly RpcService rpcService;
    private readonly ObservableCollection<object?> records = [];

    public MainWindow(RpcService rpcService)
    {
        this.rpcService = rpcService;
        rpcService.RecordReceived += OnRecordReceived;

        InitializeComponent();

        Table.ItemsSource = records;
    }

    private void OnRecordReceived(object? record)
    {
        Dispatcher.Post(() => AddRecord(record));
    }

    private void AddRecord(object? record)
    {
        if (record is not null && records.Count is 0)
        {
            if (record is PSObject psObject)
            {
                foreach (var property in psObject.Properties)
                {
                    var name = property.Name;
                    Table.Columns.Add(
                        new DataGridTextColumn()
                        {
                            Header = name,
                            Binding = CompiledBinding.Create<object, object>(
                                o => o,
                                converter: new FuncValueConverter<object, string?>(o =>
                                    (o as PSObject)?.Properties[name].Value?.ToString()
                                )
                            ),
                        }
                    );
                }
            }
            else
            {
                Table.Columns.Add(
                    new DataGridTextColumn()
                    {
                        Header = record switch
                        {
                            bool => "Boolean",
                            byte or sbyte or short or ushort or int or uint or long or ulong => "Integer",
                            float or double or decimal => "Number",
                            char => "Character",
                            string => "String",
                            _ => "Primitive",
                        },
                        Binding = CompiledBinding.Create<object, object>(
                            o => o,
                            converter: new FuncValueConverter<object, string?>(o => o?.ToString())
                        ),
                    }
                );
            }
        }

        records.Add(record);
    }

    protected override void OnClosed(EventArgs e)
    {
        rpcService.RecordReceived -= OnRecordReceived;

        base.OnClosed(e);
    }
}