Files
ShrlAlgoToolkit/Melskin/Controls/Badge.xaml.cs

281 lines
9.1 KiB
C#
Raw Normal View History

2025-08-12 23:08:54 +08:00
using ContentControlBase = System.Windows.Controls.ContentControl;
2025-07-12 23:31:32 +08:00
2026-01-02 17:30:41 +08:00
namespace Melskin.Controls;
2025-08-20 12:10:13 +08:00
/// <summary>
/// Badge 控件用于在应用界面中显示数字或状态徽标。它继承自 ContentControl允许开发者通过设置属性来定制徽标的外观和行为。
/// </summary>
2025-07-12 23:31:32 +08:00
[TemplatePart(Name = PART_BadgeContainer, Type = typeof(FrameworkElement))]
[TemplatePart(Name = PART_Count, Type = typeof(ContentPresenter))]
public class Badge : ContentControlBase
2025-07-11 09:20:23 +08:00
{
2025-07-12 23:31:32 +08:00
#region Fields
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
private const string PART_BadgeContainer = "PART_BadgeContainer";
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
private const string PART_Count = "PART_Count";
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
private FrameworkElement? badgeContainer;
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
private ContentPresenter? count;
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
#endregion
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
#region Properties
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
/// <summary>
/// 用于注册Count属性的依赖属性。此属性表示徽章中显示的数字或内容。
/// </summary>
2025-07-12 23:31:32 +08:00
public static readonly DependencyProperty CountProperty =
2025-08-12 23:08:54 +08:00
DependencyProperty.Register(nameof(Count), typeof(object), typeof(Badge), new PropertyMetadata(null, OnCountChanged));
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
/// <summary>
/// Gets/sets number to show in badge
/// </summary>
public object Count
{
2025-08-12 23:08:54 +08:00
get => GetValue(CountProperty);
set => SetValue(CountProperty, value);
2025-07-12 23:31:32 +08:00
}
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
private static void OnCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
2025-08-20 12:10:13 +08:00
(d as Badge)?.ApplyCount();
2025-07-12 23:31:32 +08:00
}
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
private void ApplyCount()
{
if (count == null) return;
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
var content = Count;
2025-07-11 09:20:23 +08:00
if (Count is string str)
2025-07-12 23:31:32 +08:00
{
try
2025-07-11 09:20:23 +08:00
{
var d = int.Parse(str);
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
if (d > OverflowCount)
{
content = $"{OverflowCount}+";
2025-07-11 09:20:23 +08:00
}
}
2025-08-20 12:10:13 +08:00
catch
{
// ignored
} // 如果无法解析为整数,则保持原样
2025-07-11 09:20:23 +08:00
}
2025-07-12 23:31:32 +08:00
count.Content = content;
}
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
/// <summary>
/// 用于注册Dot属性的依赖属性。此属性表示徽章是否显示为点状形式。
/// </summary>
2025-07-12 23:31:32 +08:00
public static readonly DependencyProperty DotProperty =
2025-08-12 23:08:54 +08:00
DependencyProperty.Register(nameof(Dot), typeof(bool), typeof(Badge), new PropertyMetadata(false));
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
/// <summary>
/// Gets/sets whether to display a red dot instead of count
/// </summary>
public bool Dot
{
2025-08-12 23:08:54 +08:00
get => (bool)GetValue(DotProperty);
set => SetValue(DotProperty, value);
2025-07-12 23:31:32 +08:00
}
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
/// <summary>
/// 用于注册Offset属性的依赖属性。此属性表示徽章位置相对于其默认位置的偏移量可以用来微调徽章显示的位置。
/// </summary>
2025-07-12 23:31:32 +08:00
public static readonly DependencyProperty OffsetProperty =
2025-08-12 23:08:54 +08:00
DependencyProperty.Register(nameof(Offset), typeof(Point?), typeof(Badge), new PropertyMetadata(null));
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
/// <summary>
/// 用于设置或获取徽章相对于其默认位置的偏移量。此属性允许自定义徽章在布局中的精确位置。
/// </summary>
2025-07-12 23:31:32 +08:00
public Point? Offset
{
2025-08-12 23:08:54 +08:00
get => (Point?)GetValue(OffsetProperty);
set => SetValue(OffsetProperty, value);
2025-07-12 23:31:32 +08:00
}
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
/// <summary>
/// 用于定义当计数超过特定阈值时显示的数字。此属性允许设置一个最大值,当实际计数超出该值时,将显示这个预设的最大值。
/// </summary>
2025-07-12 23:31:32 +08:00
public static readonly DependencyProperty OverflowCountProperty =
2025-08-12 23:08:54 +08:00
DependencyProperty.Register(nameof(OverflowCount), typeof(int), typeof(Badge), new PropertyMetadata(99, OnCountChanged));
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
/// <summary>
/// Gets/sets max count to show
/// </summary>
public int OverflowCount
{
2025-08-12 23:08:54 +08:00
get => (int)GetValue(OverflowCountProperty);
set => SetValue(OverflowCountProperty, value);
2025-07-12 23:31:32 +08:00
}
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
/// <summary>
/// 用于控制当计数为0时是否显示徽章的依赖属性。如果设置为true即使计数为0也会显示徽章如果设置为false则在计数为0时不显示徽章。
/// </summary>
2025-07-12 23:31:32 +08:00
public static readonly DependencyProperty ShowZeroProperty =
2025-08-12 23:08:54 +08:00
DependencyProperty.Register(nameof(ShowZero), typeof(bool), typeof(Badge), new PropertyMetadata(false));
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
/// <summary>
/// Gets/sets whether to show badge when count is zero
/// </summary>
public bool ShowZero
{
2025-08-12 23:08:54 +08:00
get => (bool)GetValue(ShowZeroProperty);
set => SetValue(ShowZeroProperty, value);
2025-07-12 23:31:32 +08:00
}
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
/// <summary>
/// 用于注册Status属性的依赖属性。此属性表示徽章的状态可以通过设置不同的状态来改变徽章的外观或行为。
/// </summary>
2025-07-12 23:31:32 +08:00
public static readonly DependencyProperty StatusProperty =
2025-08-12 23:08:54 +08:00
DependencyProperty.Register(nameof(Status), typeof(BadgeStatus?), typeof(Badge), new PropertyMetadata(null));
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
/// <summary>
/// Gets/sets badge as a status dot
/// </summary>
public BadgeStatus? Status
{
2025-08-12 23:08:54 +08:00
get => (BadgeStatus?)GetValue(StatusProperty);
set => SetValue(StatusProperty, value);
2025-07-12 23:31:32 +08:00
}
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
/// <summary>
/// 用于注册Text属性的依赖属性。此属性表示徽章中显示的文本内容。
/// </summary>
2025-07-12 23:31:32 +08:00
public static readonly DependencyProperty TextProperty =
2025-08-12 23:08:54 +08:00
DependencyProperty.Register(nameof(Text), typeof(string), typeof(Badge), new PropertyMetadata(string.Empty));
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
/// <summary>
2025-08-20 12:10:13 +08:00
/// 用于设置或获取徽章中显示的文本内容。
2025-07-12 23:31:32 +08:00
/// </summary>
public string Text
{
2025-08-12 23:08:54 +08:00
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
2025-07-12 23:31:32 +08:00
}
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
/// <summary>
///
/// </summary>
2025-07-12 23:31:32 +08:00
public static readonly DependencyProperty BadgeHeightProperty =
2025-08-12 23:08:54 +08:00
DependencyProperty.Register(nameof(BadgeHeight), typeof(double), typeof(Badge), new PropertyMetadata(default(double)));
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
/// <summary>
/// 用于设置或获取徽章的高度。此属性控制徽章显示时的高度大小。
/// </summary>
2025-07-12 23:31:32 +08:00
public double BadgeHeight
{
2025-08-12 23:08:54 +08:00
get => (double)GetValue(BadgeHeightProperty);
set => SetValue(BadgeHeightProperty, value);
2025-07-12 23:31:32 +08:00
}
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
/// <summary>
/// 用于注册BadgeForeground属性的依赖属性。此属性定义徽章前景色比如文字颜色。
/// </summary>
2025-07-12 23:31:32 +08:00
public static readonly DependencyProperty BadgeForegroundProperty =
2025-08-12 23:08:54 +08:00
DependencyProperty.Register(nameof(BadgeForeground), typeof(Brush), typeof(Badge), new PropertyMetadata(default(Brush)));
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
/// <summary>
/// 用于设置或获取徽章前景色的依赖属性。此属性决定了徽章中文本的颜色。
/// </summary>
2025-07-12 23:31:32 +08:00
public Brush BadgeForeground
{
2025-08-12 23:08:54 +08:00
get => (Brush)GetValue(BadgeForegroundProperty);
set => SetValue(BadgeForegroundProperty, value);
2025-07-12 23:31:32 +08:00
}
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
/// <summary>
/// 用于注册BadgeBackground属性的依赖属性。此属性定义徽章的背景颜色或画刷。
/// </summary>
2025-07-12 23:31:32 +08:00
public static readonly DependencyProperty BadgeBackgroundProperty =
2025-08-12 23:08:54 +08:00
DependencyProperty.Register(nameof(BadgeBackground), typeof(Brush), typeof(Badge), new PropertyMetadata(default(Brush)));
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
/// <summary>
/// 用于设置或获取徽章背景颜色的画刷。此属性定义了徽章显示时的背景颜色。
/// </summary>
2025-07-12 23:31:32 +08:00
public Brush BadgeBackground
{
2025-08-12 23:08:54 +08:00
get => (Brush)GetValue(BadgeBackgroundProperty);
set => SetValue(BadgeBackgroundProperty, value);
2025-07-12 23:31:32 +08:00
}
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
#endregion
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
#region Constructors
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
static Badge()
{
2025-08-12 23:08:54 +08:00
DefaultStyleKeyProperty.OverrideMetadata(typeof(Badge), new FrameworkPropertyMetadata(typeof(Badge)));
2025-07-12 23:31:32 +08:00
}
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
#endregion
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
#region Overrides
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
/// <inheritdoc />
2025-07-12 23:31:32 +08:00
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
badgeContainer = GetTemplateChild(PART_BadgeContainer) as FrameworkElement;
count = GetTemplateChild(PART_Count) as ContentPresenter;
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
ApplyCount();
}
2025-07-11 09:20:23 +08:00
2025-08-20 12:10:13 +08:00
/// <inheritdoc />
protected override Size ArrangeOverride(Size arrangeBounds)
2025-07-12 23:31:32 +08:00
{
var result = base.ArrangeOverride(arrangeBounds);
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
if (badgeContainer == null) return result;
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
var desiredSize = badgeContainer.DesiredSize;
2025-07-11 09:20:23 +08:00
2025-07-12 23:31:32 +08:00
var h = 0 - desiredSize.Width / 2;
var v = 0 - desiredSize.Height / 2;
return result;
2025-07-11 09:20:23 +08:00
}
2025-07-12 23:31:32 +08:00
#endregion
}
2025-08-20 12:10:13 +08:00
/// <summary>
///
/// </summary>
2025-07-12 23:31:32 +08:00
public enum BadgeStatus : byte
{
2025-08-20 12:10:13 +08:00
/// <summary>
/// 表示徽章状态为成功。当应用此状态时,徽章将使用预定义的样式来表示操作或状态的成功完成。
/// </summary>
Success,
/// <summary>
/// 表示徽章状态为处理中。当应用此状态时,徽章将使用预定义的样式来表示操作或流程正在进行中。
/// </summary>
Processing,
/// <summary>
/// 表示徽章状态为默认。当没有特别指定其他状态时,使用此状态来表示一般或初始的状态。
/// </summary>
Default,
/// <summary>
/// 表示徽章状态为错误。当应用此状态时,徽章将使用预定义的样式来表示操作或状态中出现的错误。
/// </summary>
Error,
/// <summary>
/// 表示徽章状态为警告。当应用此状态时,徽章将使用预定义的样式来表示需要注意或有潜在问题的情况。
/// </summary>
Warning
2025-07-11 09:20:23 +08:00
}