using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Templates; using Avalonia.Data; using Avalonia.Layout; using Avalonia.Metadata; namespace Ursa.Controls; public class Breadcrumb: ItemsControl { private static readonly ITemplate _defaultPanel = new FuncTemplate(() => new StackPanel() { Orientation = Orientation.Horizontal }); public static readonly StyledProperty IconBindingProperty = AvaloniaProperty.Register( nameof(IconBinding)); [AssignBinding] [InheritDataTypeFromItems(nameof(ItemsSource))] public IBinding? IconBinding { get => GetValue(IconBindingProperty); set => SetValue(IconBindingProperty, value); } public static readonly StyledProperty CommandBindingProperty = AvaloniaProperty.Register( nameof(CommandBinding)); [AssignBinding] [InheritDataTypeFromItems(nameof(ItemsSource))] public IBinding? CommandBinding { get => GetValue(CommandBindingProperty); set => SetValue(CommandBindingProperty, value); } public static readonly StyledProperty CommandParameterBindingProperty = AvaloniaProperty.Register( nameof(CommandParameterBinding)); [AssignBinding] [InheritDataTypeFromItems(nameof(ItemsSource))] public IBinding? CommandParameterBinding { get => GetValue(CommandParameterBindingProperty); set => SetValue(CommandParameterBindingProperty, value); } public static readonly StyledProperty SeparatorProperty = AvaloniaProperty.Register( nameof(Separator)); /// /// Separator between items. /// Usage: Separator can only be raw string or ITemplate<Control>. /// public object? Separator { get => GetValue(SeparatorProperty); set => SetValue(SeparatorProperty, value); } public static readonly StyledProperty IconTemplateProperty = AvaloniaProperty.Register( nameof(IconTemplate)); public IDataTemplate? IconTemplate { get => GetValue(IconTemplateProperty); set => SetValue(IconTemplateProperty, value); } static Breadcrumb() { ItemsPanelProperty.OverrideDefaultValue(_defaultPanel); } protected override bool NeedsContainerOverride(object? item, int index, out object? recycleKey) { return NeedsContainer(item, out recycleKey); } protected override Control CreateContainerForItemOverride(object? item, int index, object? recycleKey) { return new BreadcrumbItem(); } protected override void PrepareContainerForItemOverride(Control container, object? item, int index) { // base.PrepareContainerForItemOverride(container, item, index); if (container is not BreadcrumbItem breadcrumbItem) return; if (!breadcrumbItem.IsSet(BreadcrumbItem.SeparatorProperty)) { if (GetSeparatorInstance(Separator) is { } a) { breadcrumbItem.Separator = a; } SeparatorProperty.Changed.AddClassHandler((_, args) => { if (GetSeparatorInstance(args.NewValue.Value) is { } b) breadcrumbItem.Separator = b; }); } PseudolassesExtensions.Set(container.Classes, BreadcrumbItem.PC_Last, index == ItemCount - 1); if (container == item) return; if(!breadcrumbItem.IsSet(ContentControl.ContentProperty)) { breadcrumbItem.SetCurrentValue(ContentControl.ContentProperty, item); if (DisplayMemberBinding is not null) { breadcrumbItem[!ContentControl.ContentProperty] = DisplayMemberBinding; } } if (!breadcrumbItem.IsSet(ContentControl.ContentTemplateProperty) && this.ItemTemplate != null) { breadcrumbItem.SetCurrentValue(ContentControl.ContentTemplateProperty, this.ItemTemplate); } if (!breadcrumbItem.IsSet(BreadcrumbItem.IconProperty) && IconBinding != null) { breadcrumbItem[!BreadcrumbItem.IconProperty] = IconBinding; } if (!breadcrumbItem.IsSet(BreadcrumbItem.CommandProperty) && CommandBinding != null) { breadcrumbItem[!BreadcrumbItem.CommandProperty] = CommandBinding; } if (!breadcrumbItem.IsSet(BreadcrumbItem.CommandParameterProperty) && CommandParameterBinding != null) { breadcrumbItem[!BreadcrumbItem.CommandParameterProperty] = CommandParameterBinding; } if (!breadcrumbItem.IsSet(BreadcrumbItem.IconTemplateProperty) && IconTemplate != null) { breadcrumbItem.IconTemplate = IconTemplate; } } private static object? GetSeparatorInstance(object? separator) => separator switch { null => null, string s => s, ITemplate t => t.Build(), _ => separator.ToString() }; }