168 lines
4.8 KiB
C#
168 lines
4.8 KiB
C#
|
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]);
|
||
|
}
|
||
|
}
|