AvaloniaUI TreeViewの使い方
やりたいこと
Visual Studio 2022 + AvaloniaUI環境でTreeViewを使いたい。
使用環境
Windows 11 : Home 22H2 + Visual Studio Community 2022(64bit)
Linuxテスト環境 : 上記Windows上のWSL2 Ubuntsu 22.04.2 LTS
Visual Studio2022, AvaloniaUI 11.0.2
公式ドキュメント
下記に公式ドキュメントがあるが、いろいろな前提が省略されているので初めて使うとき
は結構こまった。
下記も参考にした
実装詳細
Nodeクラスの作成
まずTreeViewのNodeとなるNodeクラスを作る。
下位のノードをSubNodeプロパティとして保持し、ObservableCollection<Node>?型にする。表示名称としてTitleプロパティを準備する。
namespace TestApp.Models
{
public class Node
{
public ObservableCollection<Node>? SubNodes { get; }
public string Title { get; }
public Node(string title)
{
Title = title;
}
public Node(string title, ObservableCollection<Node> subNodes)
{
Title = title;
SubNodes = subNodes;
}
}
}
ViewModelを作る
TreeView本体のViewModelクラスを作る。ここではProjectViewという名称でTreeViewを作っているので、ProjectViewModelという名称のクラスを作っている。
保持するNodeとしてObservableCollection<Node> Nodesをプロパティとして持たせている。コンストラクタで仮Nodeデータを作ってNodesを初期化している。
namespace TestApp.ViewModels
{
public class ProjectViewModel : ViewModelBase
{
public ObservableCollection<Node> Nodes { get; }
public ProjectViewModel()
{
Nodes = new ObservableCollection<Node>
{
new Node("Animals", new ObservableCollection<Node>
{
new Node("Mammals", new ObservableCollection<Node>
{
new Node("Lion"), new Node("Cat"), new Node("Zebra")
})
})
};
}
}
}
xamlでTreeViewを作る
xaml全体は下記のようになった
<UserControl
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:TestApp.ViewModels"
xmlns:views="clr-namespace:TestApp.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="TestApp.Views.ProjectView"
x:DataType="vm:ProjectViewModel"
>
<Design.DataContext>
<!-- This only sets the DataContext for the previewer in an IDE,
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
<vm:ProjectViewModel />
</Design.DataContext>
<TreeView ItemsSource="{Binding Nodes}">
<TreeView.ItemTemplate>
<TreeDataTemplate ItemsSource="{Binding SubNodes}">
<TextBlock Text="{Binding Title}"/>
</TreeDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</UserControl>
xmlのネームスペース定義
まず vm = ViewModelとviews = Viewのnamespace定義をする
xmlns:vm="clr-namespace:TestApp.ViewModels"
xmlns:views="clr-namespace:TestApp.Views"
IDE用DataContextの宣言
TreeViewのBindingはDataContextの内容に対して行われる。IDEにDataContextを認識させるために下記のようにTestApp.ViewModels.ProjectViewModelをDataContextとして宣言する。
ただし、下記のコメントに記載されている通り、これはあくまでIDE用の宣言であり、コードでも別途DataContextの初期化が必要。これをやらないとProjectViewModelに対するインテリセンスが効かない。
<Design.DataContext>
<!-- This only sets the DataContext for the previewer in an IDE,
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
<vm:ProjectViewModel />
</Design.DataContext>
クラスとデータタイプを設定。
x:Class="TestApp.Views.ProjectView"
x:DataType="vm:ProjectViewModel"
TreeViewの宣言
ItemTemplete内でNodeに対するインテリセンスが効かない。けど動く。
ItemTemplateにもインテリセンスを効かせられないかいろいろやったけど、うまく動かすことができなかった。
<TreeView ItemsSource="{Binding Nodes}">
<TreeView.ItemTemplate>
<TreeDataTemplate ItemsSource="{Binding SubNodes}">
<TextBlock Text="{Binding Title}"/>
</TreeDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
DataContextの設定
ViewModelはprojectview.axaml.csで定義する必要がある
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using RtlEditor2.ViewModels;
using System.Collections.ObjectModel;
namespace TestApp.Views
{
public partial class ProjectView : UserControl
{
public ProjectView()
{
InitializeComponent();
DataContext = new ProjectViewModel();
}
}
}
さらに詳細な実装
アイコン追加したり、各種イベント/プロパティの処理を追加するやり方は以下参照
Discussion