和之前一样,先来看看效果:

  

  这个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的更多相关文章

  1. WPF自定义控件二:Border控件与TextBlock控件轮播动画

    需求:实现Border轮播动画与TextBlock动画 XAML代码如下: <Window.Resources> <Storyboard x:Key="OnLoaded1& ...

  2. WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展

    一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要是对文本 ...

  3. 【转】WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展

    一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要是对文本输入控件进行样式开发,及相关扩展功能开发,主要内容包括: 基本文 ...

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

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

  5. 工作记录--WPF自定义控件,实现一个可设置编辑模式的TextBox

    原文:工作记录--WPF自定义控件,实现一个可设置编辑模式的TextBox 1. 背景 因为最近在使用wpf开发桌面端应用,在查看页面需要把TextBox和Combox等控件设置为只读的.原本是个很简 ...

  6. WPF自定义控件与样式(1)-矢量字体图标(iconfont)

    一.图标字体 图标字体在网页开发上运用非常广泛,具体可以网络搜索了解,网页上的运用有很多例子,如Bootstrap.但在C/S程序中使用还不多,字体图标其实就是把矢量图形打包到字体文件里,就像使用一般 ...

  7. WPF自定义控件与样式(2)-自定义按钮FButton

    一.前言.效果图 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 还是先看看效果 ...

  8. WPF自定义控件与样式(15)-终结篇 & 系列文章索引 & 源码共享

    系列文章目录  WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与样式(3)-TextBox & Ric ...

  9. WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Che ...

  10. WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 日历控 ...

随机推荐

  1. 【Java/Android性能优化1】Android性能调优

    本文参考:http://www.trinea.cn/android/android-performance-demo/ 本文主要分享自己在appstore项目中的性能调优点,包括同步改异步.缓存.La ...

  2. c#几个小例子引发的思考

    楚广明老师的c#教程每一节都会给出几个小例子让大家联系,对于初学者来说这确实是一件很纠结的事情,下面我把这几个小例子简单的写一下.同时看一下我们学到了什么 1.面向过程版的圆周长面积计算 using ...

  3. Oracle基础—表分区

    一:表分区的应用场景 用于管理包含大量数据的表. 二:表分区的优点 1.提高数据的可以性 2.减少管理负担 3.改善语句的性能 三:分区的方式:(区间分区.散列分区.列表分区.组合分区) 1.区间分区 ...

  4. Oracle基础<1>--数据库设计

    一:为什么需要使用数据库设计 数据库设计可以使数据库通过健壮的数据库结构  高效并且健康  的进行工作. 二.数据库设计原则 (数据库设计.系统设计.架构设计) 1.熟悉需求 保证之后需求的变更 不会 ...

  5. 剑指Offer37 二叉树深度与平衡二叉树判断

    /************************************************************************* > File Name: 37_TreeDe ...

  6. 初识--Ajax & Json

    1,AJAX是一种进行页面局部异步刷新技术. 用AJAX向服务器发送请求和获得服务器返回的数据并更新到页面中. 不是刷新整个页面,而是在HTML页面中使用JavaScript创建XMLHTTPRequ ...

  7. asp.net获取select值的方法

    如何使用asp.net获取select值?搜索中发现一个不错的例子,在此与大家分享. 代码: <select runat="server" class="xgxxb ...

  8. iOS UIView常用方法和属性

    UIView常用方法 addSubView: // 添加子视图 insertSubview: atIndex // 视图插入到指定索引位置 insertSubview:aboveSubview: // ...

  9. 在window 下安装Memcache详解

    有时候我们需要在本地测试的时候就用到memcahce,如果本地没有安装memcache,就会有下面的错误提示: 1234567 系统发生错误 您可以选择 [ 重试 ] [ 返回 ] 或者 [ 回到首页 ...

  10. 网络HTTP、JSON、XML解析等 复习

    一.一个HTTP请求的基本要素1.请求URL:客户端通过哪个路径找到服务器 2.请求参数:客户端发送给服务器的数据* 比如登录时需要发送的用户名和密码 3.返回结果:服务器返回给客户端的数据* 一般是 ...