WPF 自定义控件并使用(例如带水印和字体图标的文本框)

一睹为快

 创建方式:

  1. 先创建用户使用控件(UserControl)
  2. 修改用户使用控件前台代码左上角UserControl改为TextBox,后台带代码将UserControl替换为TextBox目的是让其控件继承TextBox控件,注意当前图中
    前台代码效果图:

    后台的代码效果图:

  3. 创建依赖属性:

    输入快捷键propdp双击Tab键生成代码

    public int MyProperty
            {
                get { return (int)GetValue(MyPropertyProperty); }
                set { SetValue(MyPropertyProperty, value); }
            }
            public static readonly DependencyProperty MyPropertyProperty =
                DependencyProperty.Register("MyProperty", typeof(int), typeof(ownerclass), new PropertyMetadata(0));
    

    提示:int 是你控件属性的类型,MyProperty是控件属性名称,MypropertyProperty是依赖属性名称,ownerclass是自定义控件名称,new PropertyMetadata(0)中的0是默认值(必填),切记相同颜色的文字都是一一对应的 必须相同
    例如我要添加字体图标,如下代码:

    public string Ico
            {
                get { return (string)GetValue(IcoProperty); }
                set { SetValue(IcoProperty, value); }
            }
            public static readonly DependencyProperty IcoProperty =
                DependencyProperty.Register("Ico", typeof(string), typeof(LayuiTextBox), new PropertyMetadata("\xf007"));
    

返回前台代码修改其控件样式(d:DesignHeight="50" d:DesignWidth="200"-->>>是指当前界面模拟设计宽高),用鼠标右击当前界面选中编辑模板中的编辑副本,此时我们VS工具将自动在当前界面中显示改控件用到的所有内容,如图:

  5.修改ControlTemplate中的样式,我们直接在Border中Grid,并且在Grid中加入两列,一列存放字体图标,另一列存放输入框的内容,如上图中Name为ico的TextBlock控件就是存字体图标,Nane为prompt和PART_ContentHost是分别为水印字体输入内容

  

<Border x:Name="border" CornerRadius="{Binding ElementName=LayTextBox,Path=BorderRadius}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Name="icoWidth" Width="50"/>
                                    <ColumnDefinition  />
                                </Grid.ColumnDefinitions>
                                <TextBlock Name="ico" Text="{Binding ElementName=LayTextBox,Path=Ico}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
                                <TextBlock Name="prompt" Grid.Column="1" Opacity="0" Margin="0,0,5,0" Text="{Binding ElementName=LayTextBox,Path=Prompt}" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock>
                                <ScrollViewer Grid.Column="1" x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" Grid.ColumnSpan="2" Margin="0,0,5,0"/>
                            </Grid>
                        </Border>

  注意:红色背景文字中Text内容是在绑定我们在后台中注册的Ico属性,此Ico是用来传值,Binding ElementName=LayTextBox,Path=Ico是在说寻找当前控件LayTextBox中的Ico属性名称,ElementName是指当前控件名称,Path为属性名称

  6.设置触发器

<ControlTemplate.Triggers>
                            <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},Path=IcoStatus}" Value="false">
                                <Setter TargetName="icoWidth" Property="Width" Value="0" />
                                <Setter TargetName="PART_ContentHost" Property="Margin" Value="5,0,5,0" />
                                <Setter TargetName="prompt" Property="Margin" Value="5,0,5,0" />
                            </DataTrigger>
                            <Trigger Property="Text" Value="">
                                <Setter Property="Opacity" Value=".3" TargetName="prompt"/>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Opacity" TargetName="border" Value="0.56"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="true">
                                <Setter Property="BorderBrush" TargetName="border" Value="#D2D2D2"/>
                            </Trigger>
                            <Trigger Property="IsKeyboardFocused" Value="true">
                                <Setter Property="BorderBrush" TargetName="border" Value="#D2D2D2"/>
                            </Trigger>
 </ControlTemplate.Triggers>

  注意:DataTrigger为数据触发器,是指当用户输入相对应的值时出发的事件,如 Binding="{Binding RelativeSource={RelativeSource Self},Path=IcoStatus}" Value="false" 是在说当用户输入的值为空时将触发效果,Trigger是属性触发器档该控件属性达到一定条件下触发相对应的事件

  7.返回当前主界面调用自定义控件(LayuiTextBox),在当前主界面引用 xmlns:layui="clr-namespace:LayUI_WPF.CustomControl",这个引用是在告诉当前窗体调用当前项目LayUI_WPF中的CustomControl文件夹下面的自定义控件并取名为layui

  8.使用我们自定义好的控件<layui:LayuiTextBox Ico="" x:Name="text" Prompt="输入用户名" BorderRadius="10" FontFamily="/LayUI-WPF;component/Fonts/#FontAwesome" /> ,其中Ico就就是我们定义行的Ico属性我们可以在里面存放字体图标代码带到我们想要的效果

  9.依次类推 水印,边框 甚至带清空按钮的输入框都能实现,以下是我写好的带水印和字体图标的输入框代码

  前台代码为:

<TextBox.Resources>
        <Style x:Key="TextBoxStyle" TargetType="{x:Type TextBox}">
            <Setter Property="BorderBrush" Value="#ddd"/>
            <Setter Property="Width" Value="200"/>
            <Setter Property="Height" Value="50"/>
            <Setter Property="Foreground" Value="Black"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="AllowDrop" Value="true"/>
            <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
            <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TextBox}">
                        <Border x:Name="border" CornerRadius="{Binding ElementName=LayTextBox,Path=BorderRadius}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Name="icoWidth" Width="50"/>
                                    <ColumnDefinition  />
                                </Grid.ColumnDefinitions>
                                <TextBlock Name="ico" Text="{Binding ElementName=LayTextBox,Path=Ico}" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
                                <TextBlock Name="prompt" Grid.Column="1" Opacity="0" Margin="0,0,5,0" Text="{Binding ElementName=LayTextBox,Path=Prompt}" HorizontalAlignment="Left" VerticalAlignment="Center"></TextBlock>
                                <ScrollViewer Grid.Column="1" x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" Grid.ColumnSpan="2" Margin="0,0,5,0"/>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},Path=IcoStatus}" Value="false">
                                <Setter TargetName="icoWidth" Property="Width" Value="0" />
                                <Setter TargetName="PART_ContentHost" Property="Margin" Value="5,0,5,0" />
                                <Setter TargetName="prompt" Property="Margin" Value="5,0,5,0" />
                            </DataTrigger>
                            <Trigger Property="Text" Value="">
                                <Setter Property="Opacity" Value=".3" TargetName="prompt"/>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Opacity" TargetName="border" Value="0.56"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="true">
                                <Setter Property="BorderBrush" TargetName="border" Value="#D2D2D2"/>
                            </Trigger>
                            <Trigger Property="IsKeyboardFocused" Value="true">
                                <Setter Property="BorderBrush" TargetName="border" Value="#D2D2D2"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
            </Style.Triggers>
        </Style>
    </TextBox.Resources>

  后台代码为:

/// <summary>
    /// LayuiTextBox.xaml 的交互逻辑
    /// </summary>
    public partial class LayuiTextBox : TextBox
    {
        public LayuiTextBox()
        {
            InitializeComponent();
        }
        public string Ico
        {
            get { return (string)GetValue(IcoProperty); }
            set { SetValue(IcoProperty, value); }
        }
        public static readonly DependencyProperty IcoProperty =
            DependencyProperty.Register("Ico", typeof(string), typeof(LayuiTextBox), new PropertyMetadata("\xf007"));
        public bool IcoStatus
        {
            get { return (bool)GetValue(IcoStatusProperty); }
            set { SetValue(IcoStatusProperty, value); }
        }
        public static readonly DependencyProperty IcoStatusProperty =
            DependencyProperty.Register("IcoStatus", typeof(bool), typeof(LayuiTextBox), new PropertyMetadata(true));
        public string Prompt
        {
            get { return (string)GetValue(PromptProperty); }
            set { SetValue(PromptProperty, value); }
        }
        public static readonly DependencyProperty PromptProperty =
            DependencyProperty.Register("Prompt", typeof(string), typeof(LayuiTextBox), new PropertyMetadata("这是水印"));
        public int BorderRadius
        {
            get { return (int)GetValue(BorderRadiusProperty); }
            set { SetValue(BorderRadiusProperty, value); }
        }

        public static readonly DependencyProperty BorderRadiusProperty =
            DependencyProperty.Register("BorderRadius", typeof(int), typeof(LayuiTextBox), new PropertyMetadata(2));

    }

  最终样式图为一睹为中的样式

特别提示:字体图标为 Font Awesome

作者:会害羞的青蛙

时间:2020-3-28 18:39

原文地址:https://www.cnblogs.com/ShyFrog/p/12588718.html

时间: 2024-11-10 01:01:56

WPF 自定义控件并使用(例如带水印和字体图标的文本框)的相关文章

WPF自定义控件与样式(13)-自定义窗体Window &amp; 自适应内容大小消息框MessageBox

一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 自定义Window窗体样式: 基于自定义窗体实现自定义MessageBox消息提示框: 二.自定义Window窗体样式 自定义的Window窗体效果:   因为WPF默认的窗体比较简陋,大都需要自己实现Window窗体样式效果,基本思路很简单: 第一步:干掉默认样式:WindowStyle = Windo

WPF自定义控件与样式(14)-轻量MVVM模式实践

一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. MVVM是WPF中一个非常实用的编程模式,充分利用了WPF的绑定机制,体现了WPF数据驱动的优势.  图片来源:(WPF的MVVM) 关于MVVM网上很多介绍或者示例,本文不多做介绍了,本文的主要目的是提供一个轻量级的View Model实现,本文的主要内容: 依赖通知InotifyPropertyChanged实现: 命

WPF自定义控件与样式(15)-终结篇

原文:WPF自定义控件与样式(15)-终结篇 系列文章目录  WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式.水印.Label标签.功能扩展 WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式 WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展

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

系列文章目录  WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式.水印.Label标签.功能扩展 WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式 WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展 WPF自定义控件与样式(6)-ScrollV

在WPF中使用fortawesome之类的字体图标

我之前在博客中介绍过几个矢量图库网站,在WPF程序中,一般接触到的矢量图标资源有XAML.SVG.字体这三种格式.XAML是标准格式就不说了,SVG并不是直接支持的,不过微软提供了Expression Design可以非常方便我们将其转换为XAML格式的资源.而对于字体,虽然WPF是直接支持的,但由于字体图标其特殊性,要将其显示为图标还是需要费点劲的.本文这里就以Font-Awesome为例,介绍一下如何在WPF中使用字体图标. 首先添加一个样式,为了使用方便,建议直接做为全局样式: <Styl

在WPF中使用FontAwesome之类的字体图标

原文:在WPF中使用FontAwesome之类的字体图标 我之前在博客中介绍过几个矢量图库网站,在WPF程序中,一般接触到的矢量图标资源有XAML.SVG.字体这三种格式.XAML是标准格式就不说了,SVG并不是直接支持的,不过微软提供了Expression Design可以非常方便我们将其转换为XAML格式的资源.而对于字体,虽然WPF是直接支持的,但由于字体图标其特殊性,要将其显示为图标还是需要费点劲的.本文这里就以Font-Awesome为例,介绍一下如何在WPF中使用字体图标. 首先添加

WPF自定义控件Textbox 带水印 以及错误信息显示_02

前面写过一篇关于TextBox自定义控件 带水印以及错误信息显示的随笔 但是有一些BUG和一些功能不全面 这次基本补全 算是对上一篇的完善和升级. 前面只是实现了基本的水印信息以及错误信息显示.缺少了部分其他的功能 这次增加了以下功能: 1.限定textbox文本框输入长度 2.修复错误信息显示BUG. 3.更改显示样式 4.修改默认值赋值问题 先给大家来张图片看看 先贴出后台代码 public partial class SelfWateMarkTextbox : System.Windows

WPF自定义控件之水印文本(密码)框

首先来讲讲创建这个控件的初衷,一个让我很郁闷的问题. 公司的客户端项目采用WPF+MVVM技术实现,在近期地推客户端的过程中遇到了一个很奇葩的问题:在登录界面点击密码框就会直接闪退,没有任何提示 密码框是WPF原生的PasswordBox,这似乎没有什么不对.出现这个情况的一般是在xp系统(ghost的雨林木风版本或番茄花园),某些xp系统又不会出现. 出现这个问题的原因是因为客户的系统缺少PasswordBox使用的某种默认的字体,网上有人说是times new roman,又或者其它某种字体

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

原文:WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式.水印.Label标签.功能扩展 一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要是对文本输入控件进行样式开发,及相关扩展功能开发,主要内容包括: 基本文本框TextBox控件样式及扩展功能,实现了样式.水印.Label标签.功能扩展: 富