WPF自定义控件(二)——TextBox
和之前一样,先来看看效果:

这个TextBox可设置水印,可设置必填和正则表达式验证。
验证?没错,就是验证! 就是在输入完成后,控件一旦失去焦点就会自动验证!会根据我开放出来的“是否可以为空”属性进行验证,一旦为空,则控件变为警告样式。
但这还不是最特别的,为了各种手机号啊,邮箱啊的验证,我还开放了一个正则表达式的属性,在这个属性中填上正则表达式,同上, 一旦失去焦点就会自动验证输入的内容能否匹配正则表达式,如果不能匹配,则控件变为警告样式。
之后,代码还可以通过我开放的另一个属性来判断当前输入框的输入是否有误!
好了,来看代码吧:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ctrl="clr-namespace:KAN.WPF.XCtrl.Controls">
<Style TargetType="{x:Type ctrl:XTextBox}">
<!--StyleFocusVisual在上一篇里说了-->
<Style.Resources>
<ResourceDictionary Source="/KAN.WPF.Xctrl;component/Themes/CommonStyle.xaml"/>
</Style.Resources>
<Setter Property="FocusVisualStyle" Value="{StaticResource StyleFocusVisual}"/>
<Setter Property="BorderBrush" Value="Silver"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ctrl:XTextBox}">
<Border Name="brdText" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="true" Padding="2">
<Grid>
<ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<StackPanel Orientation="Horizontal" Visibility="Collapsed" Name="stpWatermark">
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center"
FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}"
Foreground="{Binding XWmkForeground, RelativeSource={RelativeSource TemplatedParent}}"
Text="{Binding XWmkText, RelativeSource={RelativeSource TemplatedParent}}" Cursor="IBeam" />
</StackPanel>
<ContentPresenter></ContentPresenter>
</Grid>
</Border>
<ControlTemplate.Triggers>
<!--当失去焦点并且没有输入任何内容时-->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Text" Value=""/>
<Condition Property="IsFocused" Value="False"/>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Visibility" TargetName="stpWatermark" Value="Visible"/>
</MultiTrigger.Setters>
</MultiTrigger>
<!--当验证失败时-->
<Trigger Property="XIsError" Value="true">
<Setter TargetName="brdText" Property="BorderBrush" Value="Red" />
<Setter TargetName="brdText" Property="Background" Value="Beige" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
再来看看CS:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Input;
using System.Text.RegularExpressions; namespace KAN.WPF.XCtrl.Controls
{
/// <summary>
/// 扩展输入框:可设置水印,可设置必填,可设置正则表达式验证
/// </summary>
public class XTextBox:TextBox
{
#region 依赖属性
public static readonly DependencyProperty XWmkTextProperty;//水印文字
public static readonly DependencyProperty XWmkForegroundProperty;//水印着色
public static readonly DependencyProperty XIsErrorProperty;//是否字段有误
public static readonly DependencyProperty XAllowNullProperty;//是否允许为空
public static readonly DependencyProperty XRegExpProperty;//正则表达式
#endregion #region 内部方法
/// <summary>
/// 注册事件
/// </summary>
public XTextBox()
{
this.LostFocus += new RoutedEventHandler(XTextBox_LostFocus);
this.GotFocus += new RoutedEventHandler(XTextBox_GotFocus);
this.PreviewMouseDown += new MouseButtonEventHandler(XTextBox_PreviewMouseDown);
} /// <summary>
/// 静态构造函数
/// </summary>
static XTextBox()
{
//注册依赖属性
XTextBox.XWmkTextProperty = DependencyProperty.Register("XWmkText", typeof(String), typeof(XTextBox), new PropertyMetadata(null));
XTextBox.XAllowNullProperty = DependencyProperty.Register("XAllowNull", typeof(bool), typeof(XTextBox), new PropertyMetadata(true));
XTextBox.XIsErrorProperty = DependencyProperty.Register("XIsError", typeof(bool), typeof(XTextBox), new PropertyMetadata(false));
XTextBox.XRegExpProperty = DependencyProperty.Register("XRegExp", typeof(string), typeof(XTextBox), new PropertyMetadata(""));
XTextBox.XWmkForegroundProperty = DependencyProperty.Register("XWmkForeground", typeof(Brush),
typeof(XTextBox), new PropertyMetadata(Brushes.Silver));
FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(XTextBox), new FrameworkPropertyMetadata(typeof(XTextBox)));
} /// <summary>
/// 失去焦点时检查输入
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void XTextBox_LostFocus(object sender, RoutedEventArgs e)
{
this.XIsError = false;
if (XAllowNull == false && this.Text.Trim() == "")
{
this.XIsError = true;
}
if (Regex.IsMatch(this.Text.Trim(), XRegExp) == false)
{
this.XIsError = true;
}
} /// <summary>
/// 获得焦点时选中文字
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void XTextBox_GotFocus(object sender, RoutedEventArgs e)
{
this.SelectAll();
} /// <summary>
/// 鼠标点击时选中文字
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void XTextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
if (this.IsFocused == false)
{
TextBox textBox = e.Source as TextBox;
textBox.Focus();
e.Handled = true;
}
}
#endregion #region 公布属性
/// <summary>
/// 公布属性XWmkText(水印文字)
/// </summary>
public String XWmkText
{
get
{
return base.GetValue(XTextBox.XWmkTextProperty) as String;
}
set
{
base.SetValue(XTextBox.XWmkTextProperty, value);
}
} /// <summary>
/// 公布属性XWmkForeground(水印着色)
/// </summary>
public Brush XWmkForeground
{
get
{
return base.GetValue(XTextBox.XWmkForegroundProperty) as Brush;
}
set
{
base.SetValue(XTextBox.XWmkForegroundProperty, value);
}
} /// <summary>
/// 公布属性XIsError(是否字段有误)
/// </summary>
public bool XIsError
{
get
{
return (bool)base.GetValue(XTextBox.XIsErrorProperty);
}
set
{
base.SetValue(XTextBox.XIsErrorProperty, value);
}
} /// <summary>
/// 公布属性XAllowNull(是否允许为空)
/// </summary>
public bool XAllowNull
{
get
{
return (bool)base.GetValue(XTextBox.XAllowNullProperty);
}
set
{
base.SetValue(XTextBox.XAllowNullProperty, value);
}
} /// <summary>
/// 公布属性XRegExp(正则表达式)
/// </summary>
public string XRegExp
{
get
{
return base.GetValue(XTextBox.XRegExpProperty) as string;
}
set
{
base.SetValue(XTextBox.XRegExpProperty, value);
}
}
#endregion
}
}
怎么样?还算不错吧!我觉得这个控件的用处算是最大的了!用上这个和上一篇的Button基本可以完成很多WPF项目了!
不过~好像还少了个主窗体!没错!下一篇就来说说怎么自定义主窗体!
有疑问的多留言哟!
WPF自定义控件(二)——TextBox的更多相关文章
- WPF自定义控件二:Border控件与TextBlock控件轮播动画
需求:实现Border轮播动画与TextBlock动画 XAML代码如下: <Window.Resources> <Storyboard x:Key="OnLoaded1& ...
- WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展
一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要是对文本 ...
- 【转】WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展
一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要是对文本输入控件进行样式开发,及相关扩展功能开发,主要内容包括: 基本文 ...
- WPF自定义控件(二)の重写原生控件样式模板
话外篇: 要写一个圆形控件,用Clip,重写模板,去除样式引用圆形图片可以有这三种方式. 开发过程中,我们有时候用WPF原生的控件就能实现自己的需求,但是样式.风格并不能满足我们的需求,那么我们该怎么 ...
- 工作记录--WPF自定义控件,实现一个可设置编辑模式的TextBox
原文:工作记录--WPF自定义控件,实现一个可设置编辑模式的TextBox 1. 背景 因为最近在使用wpf开发桌面端应用,在查看页面需要把TextBox和Combox等控件设置为只读的.原本是个很简 ...
- WPF自定义控件与样式(1)-矢量字体图标(iconfont)
一.图标字体 图标字体在网页开发上运用非常广泛,具体可以网络搜索了解,网页上的运用有很多例子,如Bootstrap.但在C/S程序中使用还不多,字体图标其实就是把矢量图形打包到字体文件里,就像使用一般 ...
- WPF自定义控件与样式(2)-自定义按钮FButton
一.前言.效果图 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 还是先看看效果 ...
- WPF自定义控件与样式(15)-终结篇 & 系列文章索引 & 源码共享
系列文章目录 WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与样式(3)-TextBox & Ric ...
- WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Che ...
- WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展
一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 日历控 ...
随机推荐
- 【Android 界面效果36】Fragment管理
要管理fragment们,需使用FragmentManager,要获取它,需在activity中调用方法getFragmentManager(). 你可以用FragmentManager来做以上事情: ...
- 【Android 界面效果32】ImageView中XML属性src和background的区别
background会根据ImageView组件给定的长宽进行拉伸,而src就存放的是原图的大小,不会进行拉伸. src是图片内容(前景),bg是背景,可以同时使用. 此外:scaleType只对sr ...
- 【开源项目3】Android快速开源框架--afinal
Afinal简介 Afinal 是一个android的sqlite orm 和 ioc 框架.同时封装了android中的http框架,使其更加简单易用: 使用finalBitmap,无需考虑bitm ...
- umbraco表单
view Model定义类 controller 创建Form @HTML.RenderPartial(“”,)
- [转]使用 HTML5 索引型数据库的待办事项简要列表
本文转自:http://www.html5rocks.com/zh/tutorials/indexeddb/todo/ <!DOCTYPE html><html> <h ...
- Linux 内存管理子系统
一.内存管理子系统 1 . 内存管理模块 功能: 虚拟地址到物理地址的映射 32位系统访问的地址一共4G: 0-3G : 应用程序 3G+896M :直接映射 , Vmollat区,永久内存映射,固定 ...
- JavaScript原型(链)学习笔记
javascript是基于原型的一门脚本语言,那究竟原型是什么? 本文将从以下几个方面重点阐述原型 构造函数是什么? 构造函数和我们常见的Array String有什么关系? 原型的使用? __pro ...
- ASP.NET MVC 4 SimpleMembership Provider (1)
新的ASP.NET MVC 4.0 提供了一个新的Membership Provider,叫SimpleMembership. 首先,我们建立一个新的solution 首先我们先看一下web.conf ...
- 收藏的js学习小例子
1.js模拟java里的Map function Map(){ var obj = {} ; this.put = function(key , value){ obj[key] = value ; ...
- IoC容器的初始化过程
1.简单来说,IoC容器的初始化是由前面介绍的refresh()方法来启动的,这个方法标志着IoC容器的正式启动. 2.具体来说,这个启动包括BeanDefinition的Resource定位.载入和 ...