wpf 如何7步写一个badge控件

news/2024/11/13 10:51:18/文章来源:https://www.cnblogs.com/lvpp13/p/18354811

首先看一下效果:

 任意控件可以附加一个文字在控件的右上角,并带有红色背景

第一步,新建一个空的wpf项目:

第二步,创建一个类,取名为badge:

第三步,将badge的父类设置成  System.Windows.Documents.Adorner

    public class Badge : Adorner{public Badge(UIElement adornedElement) : base(adornedElement){}}

里面的adornedElement表示badge后面附加的对象

关于Adorner这个类的说明,微软给了相应的教程     https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/controls/adorners-overview?view=netframeworkdesktop-4.8

也可以F11查看Adorner类的说明.

 

第4步,给badge添加一个Content的附加属性:

        public static readonly DependencyProperty ContentProperty;static Badge(){ContentProperty = DependencyProperty.RegisterAttached("Content", typeof(string), typeof(Badge),new FrameworkPropertyMetadata(string.Empty, new PropertyChangedCallback(ContentChangedCallBack)));}

      public static string GetContent(DependencyObject obj)
      {
          return (string)obj.GetValue(ContentProperty);
      }


      public static void SetContent(DependencyObject obj, string value)
      {
          obj.SetValue(ContentProperty, value);
      }

第5步,实现content的回调方法:

private static void ContentChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
{var target = d as FrameworkElement;if (target != null){if (target.IsLoaded){var layer = AdornerLayer.GetAdornerLayer(target);if (layer != null){var Adorners = layer.GetAdorners(target);if (Adorners != null){foreach (var adorner in Adorners){if (adorner is Badge){layer.Remove(adorner);}}}layer.Add(new Badge(target));}}else{target.Loaded += (sender, ae) =>{var layer = AdornerLayer.GetAdornerLayer(target);if (layer != null){var Adorners = layer.GetAdorners(target);if (Adorners != null){foreach (var adorner in Adorners){if (adorner is Badge){layer.Remove(adorner);}}}layer.Add(new Badge(target));}};}}
}

第6步,重写一下OnRender方法:

        protected override void OnRender(DrawingContext drawingContext){var element = this.AdornedElement as FrameworkElement;Rect adornedElementRect = new Rect(element.DesiredSize);var point = adornedElementRect.TopRight;point.X = adornedElementRect.Right - element.Margin.Left - element.Margin.Right;SolidColorBrush renderBrush = new SolidColorBrush(Colors.Red);Pen renderPen = new Pen(new SolidColorBrush(Colors.Red), 0.5);double renderRadius = 5;var content = this.AdornedElement.GetValue(Badge.ContentProperty).ToString();FormattedText formattedText = new FormattedText(content, CultureInfo.GetCultureInfo("zh-cn"), FlowDirection.LeftToRight, new Typeface("Verdana"), 10, Brushes.White);var textWidth = formattedText.Width;var textHeight = formattedText.Height;var rectangleSizeWidth = textWidth < 15 ? 15 : textWidth;var rectangleSizeHeight = textHeight < 15 ? 15 : textHeight;var size = new Size(rectangleSizeWidth, rectangleSizeHeight);Rect rect = new Rect(new Point(point.X - rectangleSizeWidth / 2, point.Y - rectangleSizeHeight / 2), size);drawingContext.DrawRoundedRectangle(renderBrush, renderPen, rect, renderRadius, renderRadius);drawingContext.DrawText(formattedText, new Point(point.X - textWidth / 2, point.Y - textHeight / 2));}

这段代码就是在目标控件的右上角绘制一个带圆角的rectangle,背景色为红色,再绘制一个文本用来显示content.

第7步,运用到项目中:

    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"><cc:CornerButton ButtonType="OutLine" Width="200" Height="30"cc:Badge.Content="{Binding ElementName=textbox1, Path=Text, UpdateSourceTrigger=PropertyChanged}" Margin="10"/><cc:CornerTextBox x:Name="textbox1" Width="200" Height="30" Text="12"VerticalContentAlignment="Center" WaterText="BadgeContent"/></StackPanel>

cc是表示badge所在的命名空间,然后你就会发现,你改变textbox的值的时候,badge会跟着textbox的值发生变化哦.

 

项目github地址:bearhanQ/WPFFramework: Share some experience (github.com)

QQ技术交流群:332035933;

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/781736.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS 绘制扇面

参考资料:https://juejin.cn/post/7266641059282927650效果:源码:<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0&…

咪咕视频m3u8地址解析及ddCalcu参数加密逆向

本文主要讲述咪咕视频m3u8地址的解析以及使用Wasm对视频的m3u8地址进行加密得到ddCalcu参数的方法。咪咕视频m3u8地址解析及ddCalcu参数加密逆向 概述 本文主要讲述咪咕视频m3u8地址的解析以及使用Wasm对视频的m3u8地址进行加密得到ddCalcu参数的方法。 使用视频ID获取未加密的…

Vs+Qt添加ui子页面

在Qt项目中,如果要实现一个弹出子界面并包含返回按钮的功能,最合适的选择是使用 Qt Dialog Form File 来创建子界面。 Qt Dialog Form File 与 Qt Widget Form File 的区别 Qt Dialog Form File (Button Bottom) 和 Qt Dialog Form File (Button Right): 这两种文件类型用于创…

ubuntu 22.04 安装 docker(服务器从毛胚到精装)

1、用户操作 阿里云默认是 root 用户,我们一般要自己创建一个用户,然后给该用户 sudo 权限 添加用户 sudo adduser newUserName赋予sudo权限 sudo usermod -aG sudo newUserName删除用户 sudo deluser --remove-home --remove-all-files newUserName切换用户 sudo su - newUs…

Mac os的防火墙导致开的热点手机连不上

在工位上用Mac给手机开热点用,结果今天手机一直连不上Mac开的热点,最后把Mac的防火墙关了就能让手机连上了,连上了再把防火墙打开也不影响连接。

k8s技术总结(一)

在学习完docker之后,也很有必要再学习k8s的一些理论和技术。 一、基础概念 kubernetes(k8s)和docker在容器管理领域具有不同的侧重点和优势。当前docker主要关注单个容器的构建、运行和管理,而k8s则专注于大规模的容器编排和管理。k8s在以下几个特性中,更具有优势。 特性1…

TIM-定时器

TIM简介定时器类型

C# 创建 Windows Service 项目

C# 创建 WindowsService 服务项目空白处,右键选择“添加安装程序”可以看到两个控件,点击右击第一个控件,打开属性设计器,将其中的Account设置为LocalSystem(本地服务),接下来,右击上面的第二个控件,打开属性界面,设置ServiceName,和将其中的StratType设置为Automatic…

【日记】我也想喝 AD 钙(978 字)

正文周五写了一整天学海计划,周六跟了一天的编曲教程,今天则是把第三章剩下的教程跟完。最后,回旋曲写是写出来了,就是把自己听笑了。写得实在太烂了。昨天晚上买了回来的机票。9 月 10 号一早。该说不说机票是真的贵啊……同时,我发现我过去的机票,执飞飞机是波音 737-8…

Kubernetes-二进制高可用部署v1.23.x

目录高可用架构k8s集群组件ectdkube-apiserverkube-schedulerkube-controller-managerkubeletkube-proxykubectl高可用分析负载均衡节点设计1.环境准备1.1 环境规划1.2 所有节点配置host解析1.3 安装必备工具1.4 所有节点关闭防火墙、selinux、dnsmasq、swap1.5 Master01节点免…

使用Pandas和NumPy实现数据获取

公众号本文地址:https://mp.weixin.qq.com/s/Uc4sUwhjLTpOo85ubj0-QA以某城市地铁数据为例,通过提取每个站三个月15分钟粒度的上下客量数据,展示Pandas和Numpy的案例应用。数据:http://u6v.cn/5W2i8H http://u6v.cn/6hUVjk初步发现数据有三个特点::1、地铁数据的前五行是…