首先看一下效果:

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

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

wpf 如何7步写一个badge控件的更多相关文章

  1. WPF自定义控件(二)の重写原生控件样式模板

    话外篇: 要写一个圆形控件,用Clip,重写模板,去除样式引用圆形图片可以有这三种方式. 开发过程中,我们有时候用WPF原生的控件就能实现自己的需求,但是样式.风格并不能满足我们的需求,那么我们该怎么 ...

  2. appium+python:自己写的一个滑动控件的方式

    #调用方式roll_ele("ID","ele_id","7","up",3)#将控件分为7格,从底部倒数第二格向上滑动 ...

  3. 一步一步写一个简单通用的makefile(三)

    上一篇一步一步写一个简单通用的makefile(二) 里面的makefile 实现对通用的代码进行编译,这一章我将会对上一次的makefile 进行进一步的优化. 优化后的makefile: #Hel ...

  4. WPF基础知识、界面布局及控件Binding(转)

    WPF是和WinForm对应的,而其核心是数据驱动事件,在开发中显示的是UI界面和逻辑关系相分离的一种开放语言.UI界面是在XAML语言环境下开发人员可以进行一些自主设计的前台界面,逻辑关系还是基于c ...

  5. WPF基础知识、界面布局及控件Binding

    WPF是和WinForm对应的,而其核心是数据驱动事件,在开发中显示的是UI界面和逻辑关系相分离的一种开放语言.UI界面是在XAML语言环境下开发人员可以进行一些自主设计的前台界面,逻辑关系还是基于c ...

  6. WPF 构建无外观(Lookless)控件

    原文:WPF 构建无外观(Lookless)控件 构建一个用户可以使用Template属性设置外观的WPF控件需要以下几步 1.继承自System.Windows.Controls.Control 2 ...

  7. 《Programming WPF》翻译 第5章 7.控件模板

    原文:<Programming WPF>翻译 第5章 7.控件模板 如果仔细的看我们当前的TTT游戏,会发现Button对象并没有完全为我们工作.哪些TTT面板有内圆角? 图5-14 这里 ...

  8. WPF从我炫系列4---装饰控件的用法

    这一节的讲解中,我将为大家介绍WPF装饰控件的用法,主要为大家讲解一下几个控件的用法. ScrollViewer滚动条控件 Border边框控件 ViewBox自由缩放控件 1. ScrollView ...

  9. WPF教程002 - 实现Step步骤条控件

    原文:WPF教程002 - 实现Step步骤条控件 在网上看到这么一个效果,刚好在用WPF做控件,就想着用WPF来实现一下 1.实现原理 1.1.该控件分为2个模块,类似ComboBox控件分为Ste ...

  10. WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探

    原文:WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探         最近因为项目需要,开始学习如何使用WPF开发桌面程序.使用WPF一段时间之后,感 ...

随机推荐

  1. Linux安全审计之audit安装与使用

    场景 安全最重要的一步是内部安全,如何监控用户的行为是一个永恒不变的话题. audit可以详细监控用户的行为,详细到查看或修改了某个文件.这些都可以在日志中查看到. 安装 小贴士: CentOS默认已 ...

  2. Android系统启动:3-zygote篇

    Android系统启动:zygote篇 原文:http://gityuan.com/2016/02/13/android-zygote/ 基于Android 6.0的源码剖析, 分析Android启动 ...

  3. sql-labs通关笔记(上)

    sql-labs通关笔记(上) 这里我们先只讲解less-1到less-9 联合查询注入 Less-1:GET -Error based.Single quotes -string 界面 在url中加 ...

  4. 【论文阅读】RAL2020: UFOMap An Efficient Probabilistic 3D Mapping Framework That Embraces the Unknown

    Last edited time: March 31, 2023 1:30 PM Reference and prenotes Paper link:https://ieeexplore.ieee.o ...

  5. 钉钉应用开发-Python操作钉钉文档(excel版)

    钉钉应用开发-Python操作钉钉文档 一: 服务端SDK下载 服务端SDK下载 - 钉钉开放平台 (dingtalk.com) pip3 install alibabacloud_dingtalk ...

  6. 如何让其他模型也能在SemanticKernel中调用本地函数

    在SemanticKernel的入门例子中: // Import packages using Microsoft.SemanticKernel; using Microsoft.SemanticKe ...

  7. IDEA新手使用教程之使用技巧总结【详解】

    IDEA是一款功能强悍.非常好用的Java开发工具,近几年编程开发人员对IDEA情有独钟. 一.IDEA的下载 IDEA下载地址:https://www.jetbrains.com/idea/down ...

  8. 3.2 逻辑设计和硬件控制语言HCL

    在硬件设计中,用电子电路来计算对位进行运算的函数,以及在各种存储器单元中存储位.大多数现代电路技术都是用信号线上的高电压或低电压来表示不同的位值.在当前的技术中,逻辑1是用1.0伏特左右的高电压表示的 ...

  9. PHP 使用非对称加密算法

    加密的类型: 在日常设计及开发中,为确保数据传输和数据存储的安全,可通过特定的算法,将数据明文加密成复杂的密文.目前主流加密手段大致可分为单向加密和双向加密. 单向加密:通过对数据进行摘要计算生成密文 ...

  10. 基于Java+Spring+Vue仓储出入库管理系统设计和实现

    \n文末获取源码联系 感兴趣的可以先收藏起来,大家在毕设选题,项目以及论文编写等相关问题都可以给我加好友咨询 系统介绍: 网络的广泛应用给生活带来了十分的便利.所以把仓储出入库管理与现在网络相结合,利 ...