WPF实现Badge标识的示例代码
作者:WPF开发者
这篇文章主要为大家详细介绍了WPF如何实现Badge标识,文中的示例代码讲解详细,对我们学习或工作有一定帮助,感兴趣的小伙伴可以了解一下
WPF 实现 Badge 标识
框架使用.NET4 至 .NET6
Visual Studio 2022
新建 Badge.cs
继承装饰器 Adorner
增加依赖属性
Text
用来展示文本FontSize
文本大小IsShow
为布尔值用来是否显示Badge
IsShow = true
不设置其他属性时候只显示一个小红点- 如果设置了
Text
则根据文本的宽度高度绘制小圆点的大小
默认将其绘制到控件右上角。
实现代码
1)新建 Badge.cs
控件代码如下:
using System; using System.Windows; using System.Windows.Documents; using System.Windows.Media; namespace WPFDevelopers.Controls { public class Badge : Adorner { public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(Badge), new PropertyMetadata(string.Empty)); public static readonly DependencyProperty FontSizeProperty = DependencyProperty.Register("FontSize", typeof(double), typeof(Badge), new PropertyMetadata(10.0d)); public static readonly DependencyProperty IsShowProperty = DependencyProperty.RegisterAttached("IsShow", typeof(bool), typeof(Badge), new PropertyMetadata(false, OnIsBadgeChanged)); private static FrameworkElement oldFrameworkElement; private readonly double _size; private readonly string _text; public Badge(UIElement adornedElement, string text = null, double size = 0) : base(adornedElement) { _text = text; _size = size; ToolTip = text; } public string Text { get => (string) GetValue(TextProperty); set => SetValue(TextProperty, value); } public double FontSize { get => (double) GetValue(FontSizeProperty); set => SetValue(FontSizeProperty, value); } public static string GetText(UIElement element) { if (element == null) throw new ArgumentNullException("Text"); return (string) element.GetValue(TextProperty); } public static void SetText(UIElement element, string Text) { if (element == null) throw new ArgumentNullException("Text"); element.SetValue(TextProperty, Text); } public static double GetFontSize(UIElement element) { if (element == null) throw new ArgumentNullException("FontSize"); return (double) element.GetValue(FontSizeProperty); } public static void SetFontSize(UIElement element, string Text) { if (element == null) throw new ArgumentNullException("FontSize"); element.SetValue(FontSizeProperty, Text); } private static void OnIsBadgeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (e.NewValue is bool isBadge && d is FrameworkElement parent) { if (isBadge) { if (!parent.IsLoaded) parent.Loaded += Parent_Loaded; else CreateBadge(parent); } else { parent.Loaded -= Parent_Loaded; CreateBadge(parent, true); } } } private static void Parent_Loaded(object sender, RoutedEventArgs e) { if (sender is UIElement element) CreateBadge(element); } private static void CreateBadge(UIElement uIElement, bool isRemove = false) { var layer = AdornerLayer.GetAdornerLayer(uIElement); if (layer == null) return; if (isRemove && uIElement != null) { var adorners = layer.GetAdorners(uIElement); if (adorners != null) foreach (var item in adorners) if (item is Badge container) layer.Remove(container); return; } var value = GetText(uIElement); var size = GetFontSize(uIElement); var badgeAdorner = new Badge(uIElement, value, size); layer.Add(badgeAdorner); } public static bool GetIsShow(DependencyObject obj) { return (bool) obj.GetValue(IsShowProperty); } public static void SetIsShow(DependencyObject obj, bool value) { obj.SetValue(IsShowProperty, value); } protected override void OnRender(DrawingContext drawingContext) { var adornedElement = AdornedElement as FrameworkElement; var margin = adornedElement.Margin; var desiredWidth = adornedElement.DesiredSize.Width - margin.Left - margin.Right; var brush = new SolidColorBrush((Color) Application.Current.TryFindResource("WD.DangerColor")); brush.Freeze(); var radius = 5.0; var center = new Point(desiredWidth, 0); FormattedText formattedText = null; if (!string.IsNullOrEmpty(_text)) formattedText = DrawingContextHelper.GetFormattedText( _text, Brushes.White, FlowDirection.LeftToRight, _size); var pen = new Pen(Brushes.White, .3); pen.Freeze(); drawingContext.PushTransform(new MatrixTransform(Matrix.Identity)); if (formattedText != null) { var height = formattedText.Height; var width = formattedText.Width > 20 ? 20 : formattedText.Width; var isSingle = false; if (_text.Length == 1) { var max = formattedText.Width > formattedText.Height ? formattedText.Width : formattedText.Height; height = max; width = max; isSingle = true; } var startPoint = new Point(0, 0); var endPoint = new Point(0, 0); if (!isSingle) { startPoint = new Point(center.X - width / 1.4, center.Y - height / 1.8); endPoint = new Point(center.X + width / 1.4 + 6, center.Y + height / 1.8); } else { startPoint = new Point(center.X - width / 2, center.Y - height / 2); endPoint = new Point(center.X + width / 2, center.Y + height / 2); } var rect = new Rect(startPoint, endPoint); drawingContext.DrawRoundedRectangle(brush, pen, rect, 8, 8); formattedText.MaxTextWidth = width + 10; var centerRect = new Point(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2); var textPosition = new Point(centerRect.X - formattedText.Width / 2, centerRect.Y - formattedText.Height / 2); drawingContext.DrawText(formattedText, textPosition); } else { drawingContext.DrawEllipse(brush, pen, center, radius, radius); } drawingContext.Pop(); RenderOptions.SetEdgeMode(this, EdgeMode.Unspecified); } } }
2)新建 BadgeExample.xaml
使用 Badge
控件代码如下:
<UserControl x:Class="WPFDevelopers.Samples.ExampleViews.BadgeExample" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers" d:DesignHeight="450" d:DesignWidth="800" mc:Ignorable="d"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <ToggleButton x:Name="MyBadgeToggleButton" Margin="10" HorizontalAlignment="Center" Content="显示Badge" /> <StackPanel Grid.Row="1" HorizontalAlignment="Center" Orientation="Horizontal"> <Button wd:Badge.IsShow="{Binding ElementName=MyBadgeToggleButton, Path=IsChecked}" wd:Badge.Text="new" Content="Default" Style="{DynamicResource WD.PrimaryButton}" /> <Button Margin="40,0" wd:Badge.FontSize="12" wd:Badge.IsShow="{Binding ElementName=MyBadgeToggleButton, Path=IsChecked}" wd:Badge.Text="3" Content="Success" Style="{DynamicResource WD.SuccessDefaultButton}" /> <Button wd:Badge.FontSize="12" wd:Badge.IsShow="{Binding ElementName=MyBadgeToggleButton, Path=IsChecked}" wd:Badge.Text="10+" Content="Warning" Style="{DynamicResource WD.WarningDefaultButton}" /> <Button Margin="40,0" wd:Badge.IsShow="{Binding ElementName=MyBadgeToggleButton, Path=IsChecked}" wd:Badge.Text="NEW" Content="Danger" Style="{DynamicResource WD.DangerDefaultButton}" /> <Rectangle Width="100" Height="100" wd:Badge.IsShow="{Binding ElementName=MyBadgeToggleButton, Path=IsChecked}" Fill="Aqua" /> </StackPanel> </Grid> </UserControl>
效果图
以上就是WPF实现Badge标识的示例代码的详细内容,更多关于WPF Badge标识的资料请关注脚本之家其它相关文章!