using System; using System.Collections.Generic; using Avalonia; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Layout; using Avalonia.Markup.Xaml; using Avalonia.Media; using DispenserCommon.Events; namespace DispenserUI.Views.Controls; /// /// 步骤条 /// public partial class StepBar : UserControl { private const string CommonColor = "#666D80"; private const string StepColor = "#5F57FF"; public static readonly StyledProperty> NodesProperty = AvaloniaProperty.Register>(nameof(Nodes)); public static readonly StyledProperty> TypesProperty = AvaloniaProperty.Register>(nameof(Types)); public static readonly StyledProperty CurrentStepProperty = AvaloniaProperty.Register(nameof(CurrentStep)); public StepBar() { InitializeComponent(); Initialized += OnInitialized; } /// /// 步骤条节点列表 /// public List Nodes { get => GetValue(NodesProperty); set => SetValue(NodesProperty, value); } public List Types { get => GetValue(TypesProperty); set => SetValue(TypesProperty, value); } /// /// 当前步骤 /// public int CurrentStep { get => GetValue(CurrentStepProperty); set => SetValue(CurrentStepProperty, value); } private void InitializeComponent() { AvaloniaXamlLoader.Load(this); } private void OnInitialized(object? sender, EventArgs eventArgs) { RenderSteps(); this.GetObservable(CurrentStepProperty) .Subscribe(value => { CurrentStep = value; RenderSteps(); }); } /// /// 渲染步骤条 /// private void RenderSteps() { var panel = new StackPanel { Orientation = Orientation.Horizontal }; for (var i = 0; i < Nodes.Count; i++) { // 圈圈里面的索引 var indexTextBlock = new TextBlock { Text = (i + 1).ToString(), Foreground = i == CurrentStep ? Brushes.White : Brush.Parse(CommonColor), HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, TextAlignment = TextAlignment.Center, FontSize = 14, Margin = new Thickness(5, 0) }; // ⭕️序号 var indexBorder = new Border { BorderBrush = i == CurrentStep ? Brush.Parse(StepColor) : Brush.Parse(CommonColor), Background = i == CurrentStep ? Brush.Parse(StepColor) : Brushes.Transparent, Width = 20, Height = 20, CornerRadius = new CornerRadius(20), BorderThickness = new Thickness(1), Child = indexTextBlock }; // 步骤文本 var stepTextBlock = new TextBlock { Text = Nodes[i], Foreground = i == CurrentStep ? Brush.Parse(StepColor) : Brush.Parse(CommonColor), VerticalAlignment = VerticalAlignment.Center, Margin = new Thickness(5, 0) }; // 通过一个 StackPanel 将步骤文本和分隔条分隔开 var node = new StackPanel { Name = "" + i, Cursor = Cursor.Parse("Hand"), Orientation = Orientation.Horizontal, Children = { indexBorder, stepTextBlock } }; // 给当前节点添加点击事件 node.PointerPressed += (sender, args) => { // 添加点击事件 OnStepClicked(int.Parse(node.Name!)); }; panel.Children.Add(node); // 最后一个节点不需要分隔条 if (i >= Nodes.Count - 1) continue; // 分隔条 var divide = new TextBlock { Text = "———", Foreground = Brushes.DarkGray, FontWeight = FontWeight.Bold, VerticalAlignment = VerticalAlignment.Center, Margin = new Thickness(5, 0) }; panel.Children.Add(divide); } Content = panel; } /// /// 处理步骤的点击事件 /// /// private void OnStepClicked(int stepIndex) { CurrentStep = stepIndex; RenderSteps(); // 发布通知 EventBus.Publish(EventType.StepChanged, Types[stepIndex]); } }