Dispenser/DispenserUI/Views/Controls/StepBar.axaml.cs

168 lines
4.8 KiB
C#
Raw Normal View History

2024-08-16 07:20:09 +00:00
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;
/// <summary>
/// 步骤条
/// </summary>
public partial class StepBar : UserControl
{
private const string CommonColor = "#666D80";
private const string StepColor = "#5F57FF";
public static readonly StyledProperty<List<string>> NodesProperty =
AvaloniaProperty.Register<StepBar, List<string>>(nameof(Nodes));
public static readonly StyledProperty<List<Type>> TypesProperty =
AvaloniaProperty.Register<StepBar, List<Type>>(nameof(Types));
public static readonly StyledProperty<int> CurrentStepProperty =
AvaloniaProperty.Register<StepBar, int>(nameof(CurrentStep));
public StepBar()
{
InitializeComponent();
Initialized += OnInitialized;
}
/// <summary>
/// 步骤条节点列表
/// </summary>
public List<string> Nodes
{
get => GetValue(NodesProperty);
set => SetValue(NodesProperty, value);
}
public List<Type> Types
{
get => GetValue(TypesProperty);
set => SetValue(TypesProperty, value);
}
/// <summary>
/// 当前步骤
/// </summary>
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();
});
}
/// <summary>
/// 渲染步骤条
/// </summary>
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;
}
/// <summary>
/// 处理步骤的点击事件
/// </summary>
/// <param name="stepIndex"></param>
private void OnStepClicked(int stepIndex)
{
CurrentStep = stepIndex;
RenderSteps();
// 发布通知
EventBus<Type>.Publish(EventType.StepChanged, Types[stepIndex]);
}
}