基于WPF实现验证码控件
作者:驚鏵 发布时间:2021-08-15 21:44:36
标签:WPF,验证码,控件
代码如下
一、创建CheckCode.xaml代码如下
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:WPFDevelopers.Controls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Basic/ControlBasic.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="{x:Type controls:CheckCode}" BasedOn="{StaticResource ControlBasicStyle}">
<Setter Property="Background" Value="{x:Null}"/>
<Setter Property="Width" Value="100"/>
<Setter Property="Height" Value="40"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:CheckCode}">
<Image x:Name="PART_Image" Stretch="Fill" Source="{TemplateBinding ImageSource}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
二、CheckCode.cs代码如下
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace WPFDevelopers.Controls
{
[TemplatePart(Name = ImageTemplateName, Type = typeof(Image))]
public class CheckCode : Control
{
private const string ImageTemplateName = "PART_Image";
private Image _image;
private Size _size = new Size(70, 23);
private const string strCode = "abcdefhkmnprstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789";
public static readonly DependencyProperty ImageSourceProperty =
DependencyProperty.Register("ImageSource", typeof(ImageSource), typeof(CheckCode),new PropertyMetadata(null));
/// <summary>
/// 随机生成的验证码
/// </summary>
public ImageSource ImageSource
{
get { return (ImageSource)GetValue(ImageSourceProperty); }
set { SetValue(ImageSourceProperty, value); }
}
/// <summary>
/// 字体颜色
/// </summary>
public Brush SizeColor
{
get { return (Brush)GetValue(SizeColorProperty); }
set { SetValue(SizeColorProperty, value); }
}
public static readonly DependencyProperty SizeColorProperty =
DependencyProperty.Register("SizeColor", typeof(Brush), typeof(CheckCode), new PropertyMetadata(DrawingContextHelper.Brush));
public CheckCode()
{
this.Loaded += CheckCode_Loaded;
}
private void CheckCode_Loaded(object sender, RoutedEventArgs e)
{
ImageSource = CreateCheckCodeImage(CreateCode(4), (int)this.ActualWidth, (int)this.ActualHeight);
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_image = GetTemplateChild(ImageTemplateName) as Image;
if (_image != null)
_image.PreviewMouseDown += _image_PreviewMouseDown;
}
private void _image_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (!IsLoaded)
return;
ImageSource = CreateCheckCodeImage(CreateCode(4), (int)this.ActualWidth, (int)this.ActualHeight);
}
private string CreateCode(int strLength)
{
var _charArray = strCode.ToCharArray();
var randomCode = "";
int temp = -1;
Random rand = new Random(Guid.NewGuid().GetHashCode());
for (int i = 0; i < strLength; i++)
{
if (temp != -1)
rand = new Random(i * temp * ((int)DateTime.Now.Ticks));
int t = rand.Next(strCode.Length - 1);
if (!string.IsNullOrWhiteSpace(randomCode))
{
while (randomCode.ToLower().Contains(_charArray[t].ToString().ToLower()))
t = rand.Next(strCode.Length - 1);
}
if (temp == t)
return CreateCode(strLength);
temp = t;
randomCode += _charArray[t];
}
return randomCode;
}
private ImageSource CreateCheckCodeImage(string checkCode, int width, int height)
{
if (string.IsNullOrWhiteSpace(checkCode))
return null;
if (width <= 0 || height <= 0)
return null;
var drawingVisual = new DrawingVisual();
var random = new Random(Guid.NewGuid().GetHashCode());
using (DrawingContext dc = drawingVisual.RenderOpen())
{
dc.DrawRectangle(Brushes.White, new Pen(SizeColor, 1), new Rect(_size));
var formattedText = DrawingContextHelper.GetFormattedText(checkCode,color:SizeColor, flowDirection: FlowDirection.LeftToRight,textSize:20, fontWeight: FontWeights.Bold);
dc.DrawText(formattedText, new Point((_size.Width - formattedText.Width) / 2, (_size.Height - formattedText.Height) / 2));
for (int i = 0; i < 10; i++)
{
int x1 = random.Next(width - 1);
int y1 = random.Next(height - 1);
int x2 = random.Next(width - 1);
int y2 = random.Next(height - 1);
dc.DrawGeometry(Brushes.Silver, new Pen(Brushes.Silver, 0.5D), new LineGeometry(new Point(x1, y1), new Point(x2, y2)));
}
for (int i = 0; i < 100; i++)
{
int x = random.Next(width - 1);
int y = random.Next(height - 1);
SolidColorBrush c = new SolidColorBrush(Color.FromRgb((byte)random.Next(0, 255), (byte)random.Next(0, 255), (byte)random.Next(0, 255)));
dc.DrawGeometry(c, new Pen(c, 1D), new LineGeometry(new Point(x - 0.5, y - 0.5), new Point(x + 0.5, y + 0.5)));
}
dc.Close();
}
var renderBitmap = new RenderTargetBitmap(70, 23, 96, 96, PixelFormats.Pbgra32);
renderBitmap.Render(drawingVisual);
return BitmapFrame.Create(renderBitmap);
}
}
}
三、新建CheckCodeExample.cs代码如下
<UserControl x:Class="WPFDevelopers.Samples.ExampleViews.CheckCodeExample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"
xmlns:wpfdev="https://github.com/WPFDevelopersOrg/WPFDevelopers"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UniformGrid Rows="2" Columns="2">
<wpfdev:CheckCode SizeColor="LimeGreen"/>
<wpfdev:CheckCode SizeColor="Red"/>
<wpfdev:CheckCode SizeColor="DodgerBlue"/>
<wpfdev:CheckCode SizeColor="HotPink"/>
</UniformGrid>
</UserControl>
效果预览
源码地址如下
Github:https://github.com/WPFDevelopersOrg
Gitee:https://gitee.com/WPFDevelopersOrg
来源:https://mp.weixin.qq.com/s/4h6QZJZbloCAfGnIrCpJVQ


猜你喜欢
- 和之前一样首先看一下WPF钟表效果图 是不是很炫酷,上面的那个花都是带有动画效果的图片 。接下来就是代码了。首先看一下整个场景的布局搭建&l
- 本文实例为大家分享了java实现银行ATM管理系统的具体代码,供大家参考,具体内容如下功能账户类、首页设计分析① 每个用户一个账户对象,需要
- 继承的概念及定义概念:继承机制是面向对象程序设计为了提高代码复用率的一种手段,它可以保持原类特性的基础上进行拓展,简单来说继承是类层次的复用
- 双色球选号规则红球是1~33选6个,蓝球1~16选1个。它有17721088种排列组合,这个代码实现了如何将一组双色球号码 转换成第n个排列
- 本文实例为大家分享了Android实现画板的具体代码,采用的技术是双缓冲技术,供大家参考,具体内容如下1.双缓冲技术的概念所谓的双缓冲技术其
- 本文实例为大家分享了java实现推箱子游戏的具体代码,供大家参考,具体内容如下运行示例:图形界面由swing组件构成生成地图的算法如下创建地
- 本文实例讲述了Android编程简单设置ListView分割线的方法。分享给大家供大家参考,具体如下:<LinearLayout xm
- 相信大部分使用Intellij的同学都会遇到这个问题,即使项目使用了spring-boot-devtools,修改了类或者html、js等,
- Struts2 Action/动作动作是Struts2框架的核心,因为他们的任何MVC(模型 - 视图 - 控制器)框架。每个URL将被映射
- 通常我们在看一些源码时,发现全是T、?,晕乎乎的:sob:。于是,把泛型掌握好十分重要!什么是泛型Java 泛型(generics)是 JD
- 一般项目做到后期,在测试的时候,需要在测试版本和正式版本之间进行频繁的切换,怎么办呢?土豪的话可以考虑使用两台机器,同时测试,然而为了方便测
- 一、Spring启动时实现初始化的几种方式准确的说是spring容器实例化完成后,几种初始化的方式。为什么这么说呢?下看面示例:@Slf4j
- 如何从容器中获取对象有时候在项目中,我们会自己创建一些类,类中需要使用到容器中的一些类。方法是新建类并实现ApplicationContex
- 一、Sharding-JDBC简介Sharding-JDBC是Sharding-Sphere的一个产品,它有三个产品,分别是Sharding
- 前言:阻塞或唤醒一个Java线程需要操作系统切换CPU状态来完成,这种状态转换需要耗费处理器时间。如果同步代码块中的内容过于简单,状态转换消
- 最近有个需求是这样的,人民币的符号“¥”因为安卓手机系统的不一致导致符号不是完全一样,所以用美工的给的图片代替,考虑到用的地
- SpringBoot配置文件中设置server.port不生效我的配置文件为:# application.ymlserver:
- 尽管在实际开发过程中,我们一般使用ORM框架来代替传统的JDBC,例如Hibernate或者iBatis,但JDBC是Java用来实现数据访
- 本文实例为大家分享了Android利用Canvas类绘制图形的具体代码,供大家参考,具体内容如下首先介绍一下相关基础知识。1.画笔(pain
- 可以给已有实体类动态的添加字段并返回新的实体对象,不影响原来的实体对象结构。添加依赖<dependency> &n