wpf 如何7步写一个badge控件
首先看一下效果:

任意控件可以附加一个文字在控件的右上角,并带有红色背景
第一步,新建一个空的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控件的更多相关文章
- WPF自定义控件(二)の重写原生控件样式模板
话外篇: 要写一个圆形控件,用Clip,重写模板,去除样式引用圆形图片可以有这三种方式. 开发过程中,我们有时候用WPF原生的控件就能实现自己的需求,但是样式.风格并不能满足我们的需求,那么我们该怎么 ...
- appium+python:自己写的一个滑动控件的方式
#调用方式roll_ele("ID","ele_id","7","up",3)#将控件分为7格,从底部倒数第二格向上滑动 ...
- 一步一步写一个简单通用的makefile(三)
上一篇一步一步写一个简单通用的makefile(二) 里面的makefile 实现对通用的代码进行编译,这一章我将会对上一次的makefile 进行进一步的优化. 优化后的makefile: #Hel ...
- WPF基础知识、界面布局及控件Binding(转)
WPF是和WinForm对应的,而其核心是数据驱动事件,在开发中显示的是UI界面和逻辑关系相分离的一种开放语言.UI界面是在XAML语言环境下开发人员可以进行一些自主设计的前台界面,逻辑关系还是基于c ...
- WPF基础知识、界面布局及控件Binding
WPF是和WinForm对应的,而其核心是数据驱动事件,在开发中显示的是UI界面和逻辑关系相分离的一种开放语言.UI界面是在XAML语言环境下开发人员可以进行一些自主设计的前台界面,逻辑关系还是基于c ...
- WPF 构建无外观(Lookless)控件
原文:WPF 构建无外观(Lookless)控件 构建一个用户可以使用Template属性设置外观的WPF控件需要以下几步 1.继承自System.Windows.Controls.Control 2 ...
- 《Programming WPF》翻译 第5章 7.控件模板
原文:<Programming WPF>翻译 第5章 7.控件模板 如果仔细的看我们当前的TTT游戏,会发现Button对象并没有完全为我们工作.哪些TTT面板有内圆角? 图5-14 这里 ...
- WPF从我炫系列4---装饰控件的用法
这一节的讲解中,我将为大家介绍WPF装饰控件的用法,主要为大家讲解一下几个控件的用法. ScrollViewer滚动条控件 Border边框控件 ViewBox自由缩放控件 1. ScrollView ...
- WPF教程002 - 实现Step步骤条控件
原文:WPF教程002 - 实现Step步骤条控件 在网上看到这么一个效果,刚好在用WPF做控件,就想着用WPF来实现一下 1.实现原理 1.1.该控件分为2个模块,类似ComboBox控件分为Ste ...
- WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探
原文:WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探 最近因为项目需要,开始学习如何使用WPF开发桌面程序.使用WPF一段时间之后,感 ...
随机推荐
- 各种语言的OEP大全
Tips:当你看到这个提示的时候,说明当前的文章是由原emlog博客系统搬迁至此的,文章发布时间已过于久远,编排和内容不一定完整,还请谅解` 各种语言的OEP大全 日期:2017-5-19 阿珏 教程 ...
- hdu 5072 coprime不完整题解
Problem Description There are n people standing in a line. Each of them has a unique id number. Now ...
- C# pythonnet(1)_传感器数据清洗算法
Python代码如下 import pandas as pd # 读取数据 data = pd.read_csv('data_row.csv') # 检查异常值 def detect_outliers ...
- Legacy (线段树优化建图)
题目链接:Legacy - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题解: 考虑题目中一个点向区间连边,如真的对区间中的每一点分别连边后跑最短路,时间空间都要炸. 因为是一个点向 ...
- 生成数字csv
csv文件: import time import mcpi.minecraft as minecraft import mcpi.block as block mc = minecraft.Mine ...
- DVT:华为提出动态级联Vision Transformer,性能杠杠的 | NeurIPS 2021
论文主要处理Vision Transformer中的性能问题,采用推理速度不同的级联模型进行速度优化,搭配层级间的特征复用和自注意力关系复用来提升准确率.从实验结果来看,性能提升不错 来源:晓飞的算法 ...
- 树莓派安装OpenCv
树莓派安装OpenCv 更换树莓派软件源 我们选择将树莓派的软件源切换到清华大学镜像站,据笔者亲测,通过此站可以顺利安装openCV. 切换软件源需要修改两个软件源配置文件的内容. 第一个需要修改是「 ...
- 洛谷P1176
#include<iostream> #include<utility> using namespace std; typedef long long ll; #define ...
- PHP+Redis 实例【一】点赞 + 热度
前言 点赞其实是一个很有意思的功能.基本的设计思路有大致两种, 一种自然是用mysql(写了几百行的代码都还没写完,有毒)啦 数据库直接落地存储, 另外一种就是利用点赞的业务特征来扔到redis(或m ...
- 从输入URL到页面展示到底发生了什么?--01
在浏览器中输入一个URL并按下回车键后,会发生一系列复杂且有条不紊的步骤,从请求服务器到最终页面展示在你的屏幕上.这个过程可以分为以下几个关键步骤: URL 解析 DNS 查询 TCP 连接 发送 H ...