Primary WinForms APIs:
TreeView, TreeNodeBeforeExpand / AfterSelectCheckBoxes and node check state updatesPrimary Avalonia APIs:
TreeView + TreeDataTemplateTreeView.SelectedItem, TreeView.AutoScrollToSelectedItemTreeViewItem.Expanded event for lazy-load triggers| WinForms | Avalonia |
|---|---|
TreeNode hierarchy |
hierarchical view-model with Children |
BeforeExpand async population |
TreeViewItem.Expanded handler + EnsureChildrenLoadedAsync() |
AfterSelect |
SelectedItem binding + command/view-model state updates |
| built-in check boxes | CheckBox inside TreeDataTemplate for two-state or three-state logic |
WinForms C#:
treeView1.CheckBoxes = true;
treeView1.BeforeExpand += (_, e) => LoadChildrenIfNeeded(e.Node);
treeView1.AfterSelect += (_, e) => detailsPanel.Bind(e.Node.Tag);
Avalonia XAML:
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:MyApp.ViewModels"
x:DataType="vm:ExplorerTreeViewModel">
<TreeView ItemsSource="{CompiledBinding Roots}"
AutoScrollToSelectedItem="True"
SelectedItem="{CompiledBinding SelectedNode, Mode=TwoWay}">
<TreeView.ItemTemplate>
<TreeDataTemplate x:DataType="vm:TreeNodeViewModel"
ItemsSource="{CompiledBinding Children}">
<StackPanel Orientation="Horizontal" Spacing="6">
<CheckBox IsThreeState="True"
IsChecked="{CompiledBinding IsChecked, Mode=TwoWay}" />
<TextBlock Text="{CompiledBinding Name}" />
</StackPanel>
</TreeDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</UserControl>
using Avalonia.Controls;
using Avalonia.Interactivity;
var tree = new TreeView
{
ItemsSource = viewModel.Roots,
AutoScrollToSelectedItem = true
};
tree.AddHandler(TreeViewItem.ExpandedEvent, (sender, e) =>
{
if (e.Source is TreeViewItem { DataContext: TreeNodeViewModel node })
{
_ = node.EnsureChildrenLoadedAsync();
}
}, RoutingStrategies.Bubble);
EnsureChildrenLoadedAsync() with an idempotent IsLoaded flag.