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