WPF自定义控件07:FlatTextBox

简介: 本文将介绍一下自定义的文本框控件FlatTextBox,它与FlatCheckBox实现过程非常类似,它是继承自TextBox,但使用自定义的UI样式来美化界面,并添加了特有的一些依赖属性。

       在不少的应用程序中,作为基本输入的文本框(TextBox)是少不了的,它可以很方便获取用户输入的值。本文将介绍一下自定义的文本框控件FlatTextBox,它与FlatCheckBox实现过程非常类似,它是继承自TextBox,但使用自定义的UI样式来美化界面,并添加了特有的一些依赖属性。下面将详细介绍具体的实现细节。

1 WPF项目结构


    基于之前创建的WPF示例项目,在其中创建一个新的关于FlatTextBox的项目文件。本质上,FlatTextBox是继承TextBox控件,利用TextBox控件自身的属性和方法,可以减少FlatTextBox实现的难度和复杂度。首先,给出本项目文件结构,如下图所示:

1.jpg

其中的Fonts目录下存放各种图标字体文件,Style目录下存放各种控件的UI 样式定义文件,FlatComboBox.xaml就是FlatComboBox控件的样式定义文件。另外,需要将其注册到Generic.xaml文件中,示例代码如下:

<ResourceDictionaryxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:Yd.WpfControls"><ResourceDictionary.MergedDictionaries><ResourceDictionarySource="/Yd.WpfControls;component/Style/IconFont.xaml"/><ResourceDictionarySource="/Yd.WpfControls;component/Style/FlatButton.xaml"/><ResourceDictionarySource="/Yd.WpfControls;component/Style/FlatCheckBox.xaml"/><ResourceDictionarySource="/Yd.WpfControls;component/Style/FlatRadioButton.xaml"/><ResourceDictionarySource="/Yd.WpfControls;component/Style/ToggleButton.xaml"/><ResourceDictionarySource="/Yd.WpfControls;component/Style/FlatComboBox.xaml"/><ResourceDictionarySource="/Yd.WpfControls;component/Style/FlatTextBox.xaml"/></ResourceDictionary.MergedDictionaries></ResourceDictionary>

2 WPF FlatTextBox实现


    首先在Yd.WpfControls项目中添加一个类FlatTextBox.cs,它继承自TextBox控件,示例代码如下:

usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Media;
namespaceYd.WpfControls{
publicclassFlatTextBox : TextBox    {
staticFlatTextBox()
        {
DefaultStyleKeyProperty.OverrideMetadata(typeof(FlatTextBox),
newFrameworkPropertyMetadata(typeof(FlatTextBox)));
        }
publicstaticreadonlyDependencyPropertyTextTypeProperty=DependencyProperty.Register("TextType", typeof(FlatButtonType), typeof(FlatTextBox),
newPropertyMetadata(FlatButtonType.Default));
publicFlatButtonTypeTextType        {
get { return (FlatButtonType)GetValue(TextTypeProperty); }
set { SetValue(TextTypeProperty, value); }
        }
publicstaticreadonlyDependencyPropertyIsRequreProperty=DependencyProperty.Register("IsRequre", typeof(bool), typeof(FlatTextBox),
newPropertyMetadata(false));
publicboolIsRequre        {
get { return (bool)GetValue(IsRequreProperty); }
set { SetValue(IsRequreProperty, value); }
        }
publicboolIsValidate()
        {
if ( IsRequre)
            {
if (!string.IsNullOrEmpty(this.Text))
                {
TextType=FlatButtonType.Default;
returntrue;
                }
else                {
TextType=FlatButtonType.Danger;
returntrue;
                }
            }
else            {
TextType=FlatButtonType.Default;
returntrue;
            }
        }
    }
}

      其中扩展了2个依赖属性,即TextType属性和IsRequre属性,前者代表当前输入框的类型,是Default状态的,还是Warn状态的,还是Danger状态;而后者代表当前文本框是否为必输,如果值是true,则当文本框值为空的时候,会显示红色边框。当然这个验证过程通过自定义的IsValidate()方法实现。

     FlatTextBox控件的UI样式主要就是依靠FlatTextBox.xaml文件进行定义的,示例代码如下:

<ResourceDictionaryxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:Yd.WpfControls"><StyleTargetType="{x:Type local:FlatTextBox}"><SetterProperty="FontSize"Value="{x:Static local:FlatFonts.contentFontSize}"/><SetterProperty="FontFamily"Value="{x:Static local:FlatFonts.contentFontFamily}"/><SetterProperty="Background"Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/><SetterProperty="Foreground"Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/><SetterProperty="BorderThickness"Value="2"/><SetterProperty="KeyboardNavigation.TabNavigation"Value="None"/><SetterProperty="HorizontalContentAlignment"Value="Left"/><SetterProperty="FocusVisualStyle"Value="{x:Null}"/><SetterProperty="AllowDrop"Value="true"/><SetterProperty="Height"Value="28"/><SetterProperty="VerticalContentAlignment"Value="Center"/><SetterProperty="ScrollViewer.PanningMode"Value="VerticalFirst"/><SetterProperty="Stylus.IsFlicksEnabled"Value="False"/><Style.Triggers><TriggerProperty="TextType"Value="Default"><SetterProperty="Foreground"Value="{x:Static local:FlatColors.SILVER}"/><SetterProperty="BorderBrush"Value="{x:Static local:FlatColors.SILVER}"/><SetterProperty="BorderThickness"Value="2"/><SetterProperty="Template"><Setter.Value><ControlTemplateTargetType="{x:Type TextBox}"><Borderx:Name="border"Background="{TemplateBinding Background}"BorderThickness="{TemplateBinding BorderThickness}"BorderBrush="{TemplateBinding BorderBrush}"SnapsToDevicePixels="True"CornerRadius="14"Padding="10 0"><ScrollViewerx:Name="PART_ContentHost"Focusable="false"HorizontalScrollBarVisibility="Hidden"VerticalScrollBarVisibility="Hidden"/></Border><ControlTemplate.Triggers><TriggerProperty="IsEnabled"Value="false"><SetterProperty="Opacity"TargetName="border"Value="0.56"/></Trigger><TriggerProperty="IsMouseOver"Value="true"><SetterProperty="BorderBrush"TargetName="border"Value="{x:Static local:FlatColors.ASBESTOS}"/></Trigger><TriggerProperty="IsKeyboardFocused"Value="true"><SetterProperty="BorderBrush"TargetName="border"Value="{x:Static local:FlatColors.ASBESTOS}"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Trigger><TriggerProperty="TextType"Value="Warn"><SetterProperty="Foreground"Value="{x:Static local:FlatColors.SUN_FLOWER}"/><SetterProperty="BorderBrush"Value="{x:Static local:FlatColors.SUN_FLOWER}"/><SetterProperty="BorderThickness"Value="2"/><SetterProperty="Template"><Setter.Value><ControlTemplateTargetType="{x:Type TextBox}"><Borderx:Name="border"Background="{TemplateBinding Background}"BorderThickness="{TemplateBinding BorderThickness}"BorderBrush="{TemplateBinding BorderBrush}"SnapsToDevicePixels="True"CornerRadius="14"Padding="10 0"><ScrollViewerx:Name="PART_ContentHost"Focusable="false"HorizontalScrollBarVisibility="Hidden"VerticalScrollBarVisibility="Hidden"/></Border><ControlTemplate.Triggers><TriggerProperty="IsEnabled"Value="false"><SetterProperty="Opacity"TargetName="border"Value="0.56"/></Trigger><TriggerProperty="IsMouseOver"Value="true"><SetterProperty="BorderBrush"TargetName="border"Value="{x:Static local:FlatColors.ORANGE}"/></Trigger><TriggerProperty="IsKeyboardFocused"Value="true"><SetterProperty="BorderBrush"TargetName="border"Value="{x:Static local:FlatColors.ORANGE}"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Trigger><TriggerProperty="TextType"Value="Danger"><SetterProperty="Foreground"Value="{x:Static local:FlatColors.ALIZARIN}"/><SetterProperty="BorderBrush"Value="{x:Static local:FlatColors.ALIZARIN}"/><SetterProperty="BorderThickness"Value="2"/><SetterProperty="Template"><Setter.Value><ControlTemplateTargetType="{x:Type TextBox}"><Borderx:Name="border"Background="{TemplateBinding Background}"BorderThickness="{TemplateBinding BorderThickness}"BorderBrush="{TemplateBinding BorderBrush}"SnapsToDevicePixels="True"CornerRadius="14"Padding="10 0"><ScrollViewerx:Name="PART_ContentHost"Focusable="false"HorizontalScrollBarVisibility="Hidden"VerticalScrollBarVisibility="Hidden"/></Border><ControlTemplate.Triggers><TriggerProperty="IsEnabled"Value="false"><SetterProperty="Opacity"TargetName="border"Value="0.56"/></Trigger><TriggerProperty="IsMouseOver"Value="true"><SetterProperty="BorderBrush"TargetName="border"Value="{x:Static local:FlatColors.POMEGRANATE}"/></Trigger><TriggerProperty="IsKeyboardFocused"Value="true"><SetterProperty="BorderBrush"TargetName="border"Value="{x:Static local:FlatColors.POMEGRANATE}"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter></Trigger></Style.Triggers></Style></ResourceDictionary>

其中的文本框默认的字体和字体大小通过如下设置方法实现:

<Setter Property="FontSize" Value="{x:Static local:FlatFonts.contentFontSize}"/>

<Setter Property="FontFamily" Value="{x:Static local:FlatFonts.contentFontFamily}"/>

另外就是,定义了根据依赖属性TextType的值,通过触发器来设置不同的属性,从而得到不同UI样式的目的。

3 WPF FlatTextBox测试


    首先,需要重新生成一下项目文件,然后在WpfControls项目中添加自定义控件FlatTextBox,Window5.xaml部分示例代码如下:

<Windowx:Class="WpfControls.Window5"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:WpfControls="clr-namespace:Yd.WpfControls;assembly=Yd.WpfControls"xmlns:local="clr-namespace:WpfControls"mc:Ignorable="d"Title="Window5"Height="350"Width="500"><Grid><WpfControls:FlatTextBoxHorizontalAlignment="Center"Margin="0,81,0,0"Text="FlatTextBox"TextWrapping="Wrap"VerticalAlignment="Top"Width="320"Name="flattextbox1"IsRequre="True"/><WpfControls:FlatTextBoxHorizontalAlignment="Center"Margin="0,135,0,0"Text="FlatTextBox"TextWrapping="Wrap"VerticalAlignment="Top"Width="320"TextType="Warn"/><WpfControls:FlatTextBoxHorizontalAlignment="Center"Margin="0,184,0,0"Text="FlatTextBox"TextWrapping="Wrap"VerticalAlignment="Top"Width="320"TextType="Danger"/></Grid></Window>

其中的Name="flattextbox1"给控件起一个名称,这样可以在后台用C#来进行访问,下面给出后台示例代码:

usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Data;
usingSystem.Windows.Documents;
usingSystem.Windows.Input;
usingSystem.Windows.Media;
usingSystem.Windows.Media.Imaging;
usingSystem.Windows.Shapes;
namespaceWpfControls{
/// <summary>/// Window5.xaml 的交互逻辑/// </summary>publicpartialclassWindow5 : Window    {
publicWindow5()
        {
InitializeComponent();
this.flattextbox1.Text="";
this.flattextbox1.IsValidate();
        }
    }
}

运行界面如下:

2.jpg

相关文章
WPF自定义控件05:ToggleButton
本文重点介绍WPF中如何实现自定义ToggleButton控件,它是一个开关控件,通过单击来进行状态的快速切换。
5092 0
WPF自定义控件05:ToggleButton
|
人工智能 C#
WPF自定义控件库之Window窗口
本文以自定义窗口为例,简述WPF开发中如何通过自定义控件来扩展功能和样式,仅供学习分享使用,如有不足之处,还请指正。
249 5
|
XML C# 数据格式
WPF中用户控件和自定义控件
无论是在WPF中还是WinForm中,都有用户控件(UserControl)和自定义控件(CustomControl),这两种控件都是对已有控件的封装,实现功能重用。但是两者还是有一些区别,本文对这两种控件进行讲解。
|
数据可视化 前端开发 C#
WPF自定义控件的三种方式
某些场景下,我们确实需要创建新的控件。此时,理解 WPF不同控件的创建方法就显得非常重要。 WPF 提供3个用于创建控件的方法,每个方法都提供不同的灵活度。
894 1
WPF自定义控件的三种方式
|
C# 容器
WPF自定义控件10:FlatListView
在不少的应用程序中,有时候需要使用ListView控件来显示一组集合数据,这样可以从一组数据中进行选择,让数据更加的规范,便于统计和分析。本文将介绍一下自定义的列表控件FlatListView,它与FlatCheckBox实现过程非常类似,它是继承自ListView,但使用自定义的UI样式来美化界面。
584 0
WPF自定义控件10:FlatListView
WPF自定义控件09:FlatWaveButton
按钮在很多应用程序中都是必不可少的控件,如果给按钮控件添加一些动画效果,比如单击它后会显示一个水波纹扩散的动画效果,那么感觉上更加的高级。本文将介绍一下自定义水波纹按钮控件FlatWaveButton,它是一个UserControl(FlatButton)控件,自身携带UI样式和后台逻辑。
654 0
WPF自定义控件09:FlatWaveButton
|
Web App开发 C#
WPF自定义控件08:FlatRoundImage
在不少的应用程序中,用户中心的个人页面经常需要显示头像,这个当前主流的做法就是用户上传一个图片,系统进行截取并显示为一个圆形的轮廓,即圆形的照片。本文将介绍一下自定义的图片控件FlatRoundImage,它是一个UserControl控件,自身携带UI样式和后台逻辑。
655 0
WPF自定义控件08:FlatRoundImage
WPF自定义控件06:FlatComboBox
在不少的应用程序中,经常需要使用下拉框(ComboBox)控件来从类别字段中选择,这样可以限定值的范围,让数据更加的规范,便于统计和分析。本文将介绍一下自定义的下拉框控件FlatComboBox,它与FlatCheckBox实现过程非常类似,它是继承自ComboBox,但使用自定义的UI样式来美化界面。下面将详细介绍具体的实现细节。
835 0
WPF自定义控件06:FlatComboBox
WPF自定义控件04:FlatRadioButton
本文通过在WPF中引入Font Awesome图标字体来实现自定义FlatRadioButton控件的UI绘图。用户只需要在窗体上引入自定义的FlatRadioButton控件即可使用具有Flat UI效果的控件,非常方便。
610 0
WPF自定义控件04:FlatRadioButton
WPF自定义控件03:FlatCheckBox
本文通过在WPF中引入Font Awesome图标字体来实现自定义FlatCheckBox控件的UI绘图。用户只需要在窗体上引入自定义的FlatCheckBox控件即可使用具有Flat UI效果的控件,非常方便。
728 0
WPF自定义控件03:FlatCheckBox