🙆‍♀️

AvaloniaUI TreeViewのStyle指定方法

2024/03/16に公開

やりたいこと

AvaloniaUIのTreeViewでStyleを指定して見た目を変更したい。

使用環境

Windows 11 : Home 22H2 + Visual Studio Community 2022(64bit)
Linuxテスト環境 : 上記Windows上のWSL2 Ubuntsu 22.04.2 LTS
Visual Studio2022, AvaloniaUI 11.0.2

やったこと

行間隔の変更。Expand/Collapseアイコンを+/-に修正。

TreeControl.axaml
<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:ctrl="clr-namespace:AjkAvaloniaLibs.Contorls;assembly=AjkAvaloniaLibs"
             mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="400"
             x:Class="AjkAvaloniaLibs.Contorls.TreeControl">
	<TreeView
        Name="TreeView"
        x:DataType="ctrl:TreeControlViewModel"
        ItemsSource="{Binding _nodes}"
		Tapped="TreeView_Tapped"
		DoubleTapped="TreeView_DoubleTapped"
		SelectionChanged="TreeView_SelectionChanged"
        >

		<TreeView.ItemTemplate>
			<TreeDataTemplate
                x:DataType="ctrl:TreeNode"
                ItemsSource="{Binding _nodes}"
            >
				<!-- ItemはImageとTextBlockを横に並べた構造にする -->
				<StackPanel Orientation="Horizontal" Height ="14">
					<Image Source="{Binding Image}" Width="12" Height="12"/>
					<TextBlock Text="{Binding Text}" Margin="4 0 0 0" FontSize="10" />
				</StackPanel>
			</TreeDataTemplate>
		</TreeView.ItemTemplate>

		<TreeView.Resources> 
			<!-- expand/collapse 変更用 icon定義 -->
			<StreamGeometry x:Key="TreeViewItemCollapsedChevronPathData">M 0,4 4,4 4,0 6,0 6,4 10,4 10,6 6,6 6,10 4,10 4,6 0,6 0,4 Z</StreamGeometry>
			<StreamGeometry x:Key="TreeViewItemExpandedChevronPathData">M 0,4 10,4 10,6 0,6 Z</StreamGeometry>
		</TreeView.Resources> 
		<TreeView.Styles>
			<Style Selector="TreeViewItem">
				<!-- IsExpanded Propertyを更新する -->
				<Setter Property="IsExpanded" Value="{Binding Path=IsExpanded,Mode=TwoWay}"/>
				<!-- 行間隔を変更するために必要 -->
				<Setter Property="MinHeight" Value="12"/>
			</Style>
			
			<!-- expand/collapse 変更用 icon変更 -->
			<Style Selector="ToggleButton:checked /template/ Path#ChevronPath">
				<Setter Property="Data" Value="{StaticResource TreeViewItemExpandedChevronPathData}" />
			</Style>
			<Style Selector="ToggleButton:unchecked /template/ Path#ChevronPath">
				<Setter Property="Data" Value="{StaticResource TreeViewItemCollapsedChevronPathData}" />
			</Style>
			<!-- 修正。ここはないほうがよさそう。あるとnode表示位置がずれる場合がある
            <Style Selector="TreeViewItem /template/ ToggleButton#PART_ExpandCollapseChevron">
				<Setter Property="Width" Value="10"></Setter>
				<Setter Property="Height" Value="10"></Setter>
			</Style>
            -->
			
		</TreeView.Styles>
	</TreeView>
</UserControl>

行間隔を修正する

一見 StackPanelのHeightを設定するだけでいけそうだが、実際にはそれだけでは動作しなかった。

				<StackPanel Orientation="Horizontal" Height ="14">
					<Image Source="{Binding Image}" Width="12" Height="12"/>
					<TextBlock Text="{Binding Text}" Margin="4 0 0 0" FontSize="10" />
				</StackPanel>

TreeViewItemのMinHeightを変えておく必要がある。サイズ変更が効かないときにはMax/Min設定に注意が必要。

		<TreeView.Styles>
			<Style Selector="TreeViewItem">
				<!-- 行間隔を変更するために必要 -->
				<Setter Property="MinHeight" Value="12"/>
			</Style>
		</TreeView.Styles>

Expand/Collapseアイコンを変更する

下記にアイコンの変え方の記載がある。
https://github.com/AvaloniaUI/Avalonia/issues/4847

アイコン形状は下記で指定している。

			<!-- expand/collapse 変更用 icon定義 -->
			<StreamGeometry x:Key="TreeViewItemCollapsedChevronPathData">M 0,4 4,4 4,0 6,0 6,4 10,4 10,6 6,6 6,10 4,10 4,6 0,6 0,4 Z</StreamGeometry>
			<StreamGeometry x:Key="TreeViewItemExpandedChevronPathData">M 0,4 10,4 10,6 0,6 Z</StreamGeometry>

ここのStreamGeometryはパスマークアップ形式で指定する。
詳細仕様は下記にある。

https://learn.microsoft.com/ja-jp/dotnet/desktop/wpf/graphics-multimedia/path-markup-syntax?view=netframeworkdesktop-4.8

Discussion