feat: implement tree like visual.

This commit is contained in:
Dong Bin
2025-07-04 16:09:33 +08:00
parent 817eb9acc9
commit dbc41249d8
4 changed files with 49 additions and 4 deletions

View File

@@ -127,6 +127,27 @@
Background="{DynamicResource SemiPurple1}"> Background="{DynamicResource SemiPurple1}">
<TextBlock Text="Border 3" /> <TextBlock Text="Border 3" />
</Border> </Border>
<Border
Height="300"
HorizontalAlignment="Stretch"
u:Anchor.AnchorId="anchor3-1"
Background="{DynamicResource SemiPurple1}">
<TextBlock Text="Border 3-1" />
</Border>
<Border
Height="300"
HorizontalAlignment="Stretch"
u:Anchor.AnchorId="anchor3-2"
Background="{DynamicResource SemiPurple1}">
<TextBlock Text="Border 3-2" />
</Border>
<Border
Height="300"
HorizontalAlignment="Stretch"
u:Anchor.AnchorId="anchor3-3"
Background="{DynamicResource SemiPurple1}">
<TextBlock Text="Border 3-3" />
</Border>
<Border <Border
Height="300" Height="300"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
@@ -166,9 +187,13 @@
<u:Anchor.Styles> <u:Anchor.Styles>
<Style x:DataType="viewModels:AnchorItemViewModel" Selector="u|AnchorItem"> <Style x:DataType="viewModels:AnchorItemViewModel" Selector="u|AnchorItem">
<Setter Property="AnchorId" Value="{Binding AnchorId}" /> <Setter Property="AnchorId" Value="{Binding AnchorId}" />
<Setter Property="Header" Value="{Binding Header}" />
</Style> </Style>
</u:Anchor.Styles> </u:Anchor.Styles>
<u:Anchor.ItemTemplate>
<TreeDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Header}"/>
</TreeDataTemplate>
</u:Anchor.ItemTemplate>
</u:Anchor> </u:Anchor>
</Grid> </Grid>
</TabItem> </TabItem>

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
namespace Ursa.Demo.ViewModels; namespace Ursa.Demo.ViewModels;
@@ -9,7 +10,16 @@ public partial class AnchorDemoViewModel: ObservableObject
{ {
new AnchorItemViewModel { AnchorId = "anchor1", Header = "Anchor 1" }, new AnchorItemViewModel { AnchorId = "anchor1", Header = "Anchor 1" },
new AnchorItemViewModel { AnchorId = "anchor2", Header = "Anchor 2" }, new AnchorItemViewModel { AnchorId = "anchor2", Header = "Anchor 2" },
new AnchorItemViewModel { AnchorId = "anchor3", Header = "Anchor 3" }, new AnchorItemViewModel
{
AnchorId = "anchor3", Header = "Anchor 3",
Children =
[
new AnchorItemViewModel() { AnchorId = "anchor3-1", Header = "Anchor 3.1" },
new AnchorItemViewModel() { AnchorId = "anchor3-2", Header = "Anchor 3.2" },
new AnchorItemViewModel() { AnchorId = "anchor3-3", Header = "Anchor 3.3" }
]
},
new AnchorItemViewModel { AnchorId = "anchor4", Header = "Anchor 4" }, new AnchorItemViewModel { AnchorId = "anchor4", Header = "Anchor 4" },
new AnchorItemViewModel { AnchorId = "anchor5", Header = "Anchor 5" }, new AnchorItemViewModel { AnchorId = "anchor5", Header = "Anchor 5" },
new AnchorItemViewModel { AnchorId = "anchor6", Header = "Anchor 6" }, new AnchorItemViewModel { AnchorId = "anchor6", Header = "Anchor 6" },
@@ -21,4 +31,5 @@ public partial class AnchorItemViewModel: ObservableObject
{ {
[ObservableProperty] private string? _anchorId; [ObservableProperty] private string? _anchorId;
[ObservableProperty] private string? _header; [ObservableProperty] private string? _header;
public ObservableCollection<AnchorItemViewModel>? Children { get; set; }
} }

View File

@@ -18,7 +18,7 @@
<Setter Property="Template"> <Setter Property="Template">
<ControlTemplate TargetType="u:AnchorItem"> <ControlTemplate TargetType="u:AnchorItem">
<StackPanel> <StackPanel>
<ContentPresenter Content="{TemplateBinding Header}" /> <ContentPresenter Content="{TemplateBinding Header}" ContentTemplate="{TemplateBinding HeaderTemplate}" />
<ItemsPresenter Margin="8 0 0 0" ItemsPanel="{TemplateBinding ItemsPanel}" /> <ItemsPresenter Margin="8 0 0 0" ItemsPanel="{TemplateBinding ItemsPanel}" />
</StackPanel> </StackPanel>
</ControlTemplate> </ControlTemplate>

View File

@@ -44,11 +44,20 @@ public class AnchorItem : HeaderedItemsControl, ISelectable
{ {
base.OnAttachedToVisualTree(e); base.OnAttachedToVisualTree(e);
_root = this.GetLogicalAncestors().OfType<Anchor>().FirstOrDefault(); _root = this.GetLogicalAncestors().OfType<Anchor>().FirstOrDefault();
if (ItemTemplate is null && _root?.ItemTemplate is not null)
{
SetCurrentValue(ItemTemplateProperty, _root.ItemTemplate);
}
if (ItemContainerTheme is null && _root?.ItemContainerTheme is not null)
{
SetCurrentValue(ItemContainerThemeProperty, _root.ItemContainerTheme);
}
} }
protected override void OnPointerPressed(PointerPressedEventArgs e) protected override void OnPointerPressed(PointerPressedEventArgs e)
{ {
var item = new TreeViewItem(); // var item = new TreeViewItem();
base.OnPointerPressed(e); base.OnPointerPressed(e);
if (e.Handled) return; if (e.Handled) return;
if (_root is null) if (_root is null)