首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

wpf 如何7步写一个badge控件

编程知识
2024年08月12日 12:48

首先看一下效果:

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

第一步,新建一个空的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;

 

From:https://www.cnblogs.com/lvpp13/p/18354811
本文地址: http://shuzixingkong.net/article/1021
0评论
提交 加载更多评论
其他文章 为了给Javaer落地DDD,我们不得不写开源组件
本文上回书接《这是DDD建模最难的部分(其实很简单)》,欢迎关注我的同名公众号,获取框架源码。 https://mp.weixin.qq.com/s/HZKMLF0_I10iczzp2mAR-w 故事背景 2013年中,我们的Java后端团队为了落地DDD,全面引入了dotnet技术栈,具体过程和成
为了给Javaer落地DDD,我们不得不写开源组件 为了给Javaer落地DDD,我们不得不写开源组件
后端开发学习敏捷需求-->干系人分析与识别
干系人分析与识别 5W1H 干系人分析与识别 1. 干系人是什么 直接或者间接影响专题,以及被专题影响的人和组织,用户也是属于干系人,是产品直接或者间接的使用者 又叫利益相关者,指积极参与专题或者在专题中其利益可能受积极或消极影响的个人或组织 2. 为什么要分析和识别干系人 找出对专题或者产品有重要
后端开发学习敏捷需求-->干系人分析与识别
结构开发笔记(三):solidworks软件(二):小试牛刀,绘制一个立方体
前言 solidworks草图大师,基本的使用过程。 所有的零件基础都是从平面绘制开始,然后凸出来厚度。 本篇绘制一个简单的立方体,熟悉基本操作。 立方体绘制过程 选取一个平面绘制一个立方形,然后拉伸即可。 绘制矩形的方式: 功能所见即所得。 其实用2021版本,还会有动画的提示。(开始以为点进去有
结构开发笔记(三):solidworks软件(二):小试牛刀,绘制一个立方体 结构开发笔记(三):solidworks软件(二):小试牛刀,绘制一个立方体 结构开发笔记(三):solidworks软件(二):小试牛刀,绘制一个立方体
.NET 8 跨平台高性能边缘采集网关
前言 在物联网(IoT)和工业自动化领域,边缘计算设备扮演着至关重要的角色。边缘采集网关作为连接物理世界与数字世界的桥梁,负责收集传感器数据并将数据传输到云端或本地数据中心进行处理。 本文将介绍一款基于 .NET 8 的跨平台高性能边缘采集网关的开源项目。希望通过这个项目能够帮助大家搭建和部署高效的
.NET 8 跨平台高性能边缘采集网关 .NET 8 跨平台高性能边缘采集网关 .NET 8 跨平台高性能边缘采集网关
2024 年了,IT 运维监控系统都有哪些推荐?
大浪淘沙,2024 年的今天,市面上很多监控系统慢慢淡出了大家的视野,而一些新的监控系统也逐渐崭露头角。今天我们就来看看 2024 年的当下,哪些 IT 运维监控系统最值得关注。 Prometheus 毫无疑问,Prometheus 是最值得关注的监控系统,因为 Prometheus 的规范和生态都
2024 年了,IT 运维监控系统都有哪些推荐? 2024 年了,IT 运维监控系统都有哪些推荐? 2024 年了,IT 运维监控系统都有哪些推荐?
零基础学习人工智能—Python—Pytorch学习(四)
前言 接续上一篇的optimizer的学习。 optimizer 代码和上一篇文章的一样,如下: import torch import numpy as np import torch.nn as nn X = torch.tensor([1, 2, 3, 4], dtype=torch.floa
零基础学习人工智能—Python—Pytorch学习(四)
java 栈与队列
Java中的栈与队列 一、栈(Stack) 1.1 介绍 栈是一种后进先出(LIFO,Last In First Out)的数据结构。在栈中,元素的插入和删除操作都是在栈顶进行的。Java中的java.util.Stack类实现了栈的基本功能,包括push()入栈、pop()出栈、peek()查看栈
《数据资产管理核心技术与应用》读书笔记-第三章:数据血缘
《数据资产管理核心技术与应用》是清华大学出版社出版的一本图书,全书共分10章,第1章主要让读者认识数据资产,了解数据资产相关的基础概念,以及数据资产的发展情况。第2~8章主要介绍大数据时代数据资产管理所涉及的核心技术,内容包括元数据的采集与存储、数据血缘、数据质量、数据监控与告警、数据服务、数据权限
《数据资产管理核心技术与应用》读书笔记-第三章:数据血缘 《数据资产管理核心技术与应用》读书笔记-第三章:数据血缘 《数据资产管理核心技术与应用》读书笔记-第三章:数据血缘