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一段时间之后,感 ...
随机推荐
- UniRx-unirx中的对象池
UniRx-unirx中的对象池 对象池Unirxunity 对象池 一.对象池模式 <游戏设计模式-对象池模式> 1.概念 定义一个池对象,其包含了一组可重用对象. 其中每个可重用对象都 ...
- 国内外公共 DNS调研
结论 国内可以在以下DNS选择:114DNS.阿里DNS.(阿里请联系我,给我广告费^_^) 国外可以在以下DNS选择:谷歌DNS.1.1.1.1 DNS.Cisco Umbrella DNS. 国内 ...
- 深度长文解析SpringWebFlux响应式框架15个核心组件源码
Spring WebFlux 介绍 Spring WebFlux 是 Spring Framework 5.0 版本引入的一个响应式 Web 框架,它与 Spring MVC 并存,提供了一种全新的编 ...
- Mac mysql5.7.x my.cnf默认配置
配置如下 [client] port = 3306 default-character-set=utf8 [mysqld] character_set_server=utf8 datadir=/usr ...
- move语义和完美转发
move语义 值类别(value category)如下: lvalue:左值,在内存中有地址,可被程序员访问,可以放在赋值运算符左侧,也可以放在赋值运算符右侧,常见的左值有普通变量.字符串字面值&q ...
- Swift开发基础01-语法
Hello World print("Hello World") 不用编写main函数,Swift将全局范围内的首句可执行代码作为程序入口一句代码尾部可以省略分号(;),多句代码写 ...
- BootstrapTable 行内编辑解决方案:bootstrap-table-editor
最近开发的一个业务平台,是一个低代码业务平台.其中用到的了bootstrap-table组件.但是bootstrap-table自身不带编辑功能. 通过搜索发现,网上大部分的解决方案都是使用x-edi ...
- Doris failed to initialize storage reader. tablet=106408, res=[NOT_IMPLEMENTED_ERROR]to be implemented
Apache Doris 2.3 以下的版本会存在一个 bug,导致数据在合并时存在异常,在后续查询该字段数据时会提示 [1105] [HY000]: errCode = 2, detailMessa ...
- 记录一次在欧拉(openEuler22.03LTS-SP4)系统下安装(踩坑)Freeswitch1.10.11的全过程
目录 前言 安装环境 1. 下载Freeswitch 1.1 git clone 下载freeswitch库 1.2 官网下载 2. 开始安装前的工作 2.1 安装编译时需要的环境[先安装这个!] 2 ...
- 集群及分布式定时任务中间件MEE_TIMED
集群及分布式定时任务中间件MEE_TIMED 转载请著名出处:https://www.cnblogs.com/funnyzpc/p/18312521 MEE_TIMED一套开源的定时任务中间件,MEE ...