Browse Source

feat: add TreeViewItemIndentConverter for dynamic margin calculation (#18718)

Zhang Dian 4 months ago
parent
commit
33c58a965f

+ 21 - 0
src/Avalonia.Controls/Converters/TreeViewItemIndentConverter.cs

@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using Avalonia.Data.Converters;
+
+namespace Avalonia.Controls.Converters;
+
+public class TreeViewItemIndentConverter : IMultiValueConverter
+{
+    public static readonly TreeViewItemIndentConverter Instance = new();
+
+    public object? Convert(IList<object?> values, Type targetType, object? parameter, CultureInfo culture)
+    {
+        if (values.Count > 1 && values[0] is int level && values[1] is double indent)
+        {
+            return new Thickness(indent * level, 0, 0, 0);
+        }
+
+        return new Thickness(0);
+    }
+}

+ 7 - 5
src/Avalonia.Themes.Fluent/Controls/TreeViewItem.xaml

@@ -25,9 +25,6 @@
   <Thickness x:Key="TreeViewItemExpandCollapseChevronMargin">12, 0, 12, 0</Thickness>
   <StreamGeometry x:Key="TreeViewItemCollapsedChevronPathData">M 1,0 10,10 l -9,10 -1,-1 L 8,10 -0,1 Z</StreamGeometry>
   <StreamGeometry x:Key="TreeViewItemExpandedChevronPathData">M0,1 L10,10 20,1 19,0 10,8 1,0 Z</StreamGeometry>
-  <converters:MarginMultiplierConverter Indent="{StaticResource TreeViewItemIndent}"
-                                        Left="True"
-                                        x:Key="TreeViewItemLeftMarginConverter" />
 
   <ControlTheme x:Key="FluentTreeViewExpandCollapseChevron" TargetType="ToggleButton">
     <Setter Property="Margin" Value="0" />
@@ -76,8 +73,13 @@
                   MinHeight="{TemplateBinding MinHeight}"
                   TemplatedControl.IsTemplateFocusTarget="True">
             <Grid Name="PART_Header"
-                  ColumnDefinitions="Auto, *"
-                  Margin="{TemplateBinding Level, Mode=OneWay, Converter={StaticResource TreeViewItemLeftMarginConverter}}">
+                  ColumnDefinitions="Auto, *">
+              <Grid.Margin>
+                <MultiBinding Converter="{x:Static converters:TreeViewItemIndentConverter.Instance}">
+                  <Binding Path="Level" RelativeSource="{RelativeSource TemplatedParent}" />
+                  <DynamicResource ResourceKey="TreeViewItemIndent" />
+                </MultiBinding>
+              </Grid.Margin>
               <Panel Name="PART_ExpandCollapseChevronContainer"
                      Margin="{StaticResource TreeViewItemExpandCollapseChevronMargin}">
                 <ToggleButton Name="PART_ExpandCollapseChevron"

+ 7 - 6
src/Avalonia.Themes.Simple/Controls/TreeViewItem.xaml

@@ -2,9 +2,7 @@
                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                     xmlns:converters="using:Avalonia.Controls.Converters"
                     x:ClassModifier="internal">
-  <converters:MarginMultiplierConverter x:Key="LeftMarginConverter"
-                                        Indent="16"
-                                        Left="True" />
+  <x:Double x:Key="TreeViewItemIndent">16</x:Double>
 
   <ControlTheme x:Key="SimpleTreeViewItemToggleButtonTheme"
                 TargetType="ToggleButton">
@@ -45,10 +43,13 @@
                   Focusable="True"
                   TemplatedControl.IsTemplateFocusTarget="True">
             <Grid Name="PART_Header"
-                  Margin="{TemplateBinding Level,
-                                           Mode=OneWay,
-                                           Converter={StaticResource LeftMarginConverter}}"
                   ColumnDefinitions="16, *">
+              <Grid.Margin>
+                <MultiBinding Converter="{x:Static converters:TreeViewItemIndentConverter.Instance}">
+                  <Binding Path="Level" RelativeSource="{RelativeSource TemplatedParent}" />
+                  <DynamicResource ResourceKey="TreeViewItemIndent" />
+                </MultiBinding>
+              </Grid.Margin>
               <ToggleButton Name="PART_ExpandCollapseChevron"
                             Focusable="False"
                             Background="Transparent"