一、简单设置水印TextBox控件,废话不多说看代码:

  <TextBox TextWrapping="Wrap" Margin="10" Height="69"  Visibility="Visible">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused" Value="false"/>
<Condition Property="Text" Value=""/>
</MultiTrigger.Conditions>
<Setter Property="Background">
<Setter.Value>
<VisualBrush AlignmentX="Left" AlignmentY="Top" Stretch="None">
<VisualBrush.Visual>
<TextBlock Padding="5 2" Background="Transparent" TextWrapping="Wrap" Height="40" Foreground="Silver">您的评价对网友有很重要的参考作用,请认真填<LineBreak/>写,谢谢合作!</TextBlock>
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
</MultiTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>

这里的style可以单独提出来,方便多处使用。

设置之后的效果如下:

二、扩展增强TextBox

有的时候会碰到TextBox里面需要添加按钮,或者TextBox需要设置圆角。这个时候就需要添加自定义控件,添加依赖属性来扩展功能了。

2.1 添加自定义控件TextBoxEx

代码如下:

 public class TextBoxEx : TextBox
{
static TextBoxEx()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(TextBoxEx), new FrameworkPropertyMetadata(typeof(TextBoxEx)));
} public TextBoxEx()
{
CommandBindings.Add(new CommandBinding(SearchClickCommand, delegate
{
SearchClick?.Invoke(this, null);
}));
} public static RoutedUICommand SearchClickCommand = new RoutedUICommand(nameof(SearchClickCommand), nameof(SearchClickCommand), typeof(RoutedUICommand)); public event EventHandler SearchClick;
public string WaterMark
{
get { return (string)GetValue(WaterMarkProperty); }
set { SetValue(WaterMarkProperty, value); }
} public static readonly DependencyProperty WaterMarkProperty =
DependencyProperty.Register("WaterMark", typeof(string), typeof(TextBoxEx), new PropertyMetadata(null)); public ImageSource Icon
{
get { return (ImageSource)GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
} public static readonly DependencyProperty IconProperty =
DependencyProperty.Register("Icon", typeof(ImageSource), typeof(TextBoxEx), new PropertyMetadata(null)); public new Brush BorderBrush
{
get { return (Brush)GetValue(BorderBrushProperty); }
set { SetValue(BorderBrushProperty, value); }
} public static readonly new DependencyProperty BorderBrushProperty =
DependencyProperty.Register("BorderBrush", typeof(Brush), typeof(TextBoxEx), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(,,)))); public Brush MouseOverBorderBrush
{
get { return (Brush)GetValue(MouseOverBorderBrushProperty); }
set { SetValue(MouseOverBorderBrushProperty, value); }
} public static readonly DependencyProperty MouseOverBorderBrushProperty =
DependencyProperty.Register("MouseOverBorderBrush", typeof(Brush), typeof(TextBoxEx), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(,,)))); public new Brush Background
{
get { return (Brush)GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); }
} public static readonly new DependencyProperty BackgroundProperty =
DependencyProperty.Register("Background", typeof(Brush), typeof(TextBoxEx), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(,,)))); public Brush MouseOverBackground
{
get { return (Brush)GetValue(MouseOverBackgroundProperty); }
set { SetValue(MouseOverBackgroundProperty, value); }
} public static readonly DependencyProperty MouseOverBackgroundProperty =
DependencyProperty.Register("MouseOverBackground", typeof(Brush), typeof(TextBoxEx), new PropertyMetadata(Color.FromRgb(,,))); public CornerRadius CornerRadius
{
get { return (CornerRadius)GetValue(CornerRadiusProperty); }
set { SetValue(CornerRadiusProperty, value); }
} public static readonly DependencyProperty CornerRadiusProperty =
DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(TextBoxEx), new PropertyMetadata(new CornerRadius())); public IconDirection IconDirection
{
get { return (IconDirection)GetValue(IconDirectionProperty); }
set { SetValue(IconDirectionProperty, value); }
} public static readonly DependencyProperty IconDirectionProperty =
DependencyProperty.Register("IconDirection", typeof(IconDirection), typeof(TextBoxEx), new PropertyMetadata(IconDirection.Right)); } public enum IconDirection
{
Left,
Right
}

2.2 设置TextBoxEx样式

 <Style TargetType="{x:Type local:TextBoxEx}">
<Setter Property="Foreground" Value="#555558"/>
<Setter Property="Background" Value="#6a675a"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TextBoxEx}">
<Border x:Name="_border" CornerRadius="{TemplateBinding CornerRadius}" Padding="{TemplateBinding CornerRadius,Converter={StaticResource cornerRadiusToThickness} }" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="columleft" Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition x:Name="columright" Width="auto"/>
</Grid.ColumnDefinitions>
<Image Source="{TemplateBinding Icon}" Cursor="Hand" Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Center">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<i:InvokeCommandAction Command="local:TextBoxEx.SearchClickCommand"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
<ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Center" Foreground="{TemplateBinding Foreground}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Grid.Column="1"/>
<TextBlock x:Name="_txtWater" IsHitTestVisible="False" Margin="3 0 0 0" VerticalAlignment="Center" Foreground="#9f9f9f" Text="{TemplateBinding WaterMark}" Visibility="Hidden" Grid.Column="1"/>
<Image Source="{TemplateBinding Icon}" Cursor="Hand" Stretch="None" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<i:InvokeCommandAction Command="local:TextBoxEx.SearchClickCommand"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
</Grid>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="">
<Setter TargetName="_txtWater" Property="Visibility" Value="Visible" />
</DataTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IconDirection}" Value="Left">
<Setter TargetName="columright" Property="Width" Value="0" />
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IconDirection}" Value="Right">
<Setter TargetName="columleft" Property="Width" Value="0" />
</DataTrigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="{Binding MouseOverBorderBrush,RelativeSource={RelativeSource TemplatedParent}}"/>
<Setter Property="Background" Value="{Binding MouseOverBackground,RelativeSource={RelativeSource TemplatedParent}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

这里面使用了一个转换器cornerRadiusToThickness,转换器的作用是当TextBox设置了圆角之后,保证TextBox里的内容不溢出圆角。WPF转换器的使用大家可以百度。

转换器的内容如下:

  public class CornerRadiusToThickness : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Thickness result = new Thickness();
if (value is CornerRadius)
{
var tem = (CornerRadius)value;
result = new Thickness(tem.TopLeft, , tem.TopRight, );
}
return result;
} public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

另外为了触发TextBox按钮的单击事件,添加了这个两个dll文件引用,Microsoft.Expression.Interactions.dll和System.Windows.Interactivity.dll。

在顶部定义 xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

2.3 引用方法

 <local:TextBoxEx WaterMark="请输入搜索内容..." SearchClick="TextBoxEx_SearchClick" KeyDown="TextBoxEx_KeyDown" Background="#dfe1e3" VerticalAlignment="Center" MouseOverBackground="#dfe1e3" CornerRadius="13.5" IconDirection="Right" Icon="/Images/Title/search.png" Height="25" />

所有代码已经上传到github:https://github.com/caomfan/WpfDemo.git

WPF 自定义TextBox带水印控件,可设置圆角的更多相关文章

  1. WPF自定义LED风格数字显示控件

    原文:WPF自定义LED风格数字显示控件 版权声明:本文为博主原创文章,转载请注明作者和出处 https://blog.csdn.net/ZZZWWWPPP11199988899/article/de ...

  2. 【C#】wpf自定义calendar日期选择控件的样式

    原文:[C#]wpf自定义calendar日期选择控件的样式 首先上图看下样式 原理 总览 ItemsControl内容的生成 实现 界面的实现 后台ViewModel的实现 首先上图,看下样式 原理 ...

  3. WPF 自定义ItemsControl/ListBox/ListView控件样式

    一.前言 ItemsControl.ListBox.ListView这三种控件在WPF中都可作为列表信息展示控件.我们可以通过修改这三个控件的样式来展示我们的列表信息. 既然都是展示列表信息的控件,那 ...

  4. WPF自定义TextBox及ScrollViewer

    原文:WPF自定义TextBox及ScrollViewer 寒假过完,在家真心什么都做不了,可能年龄大了,再想以前那样能专心坐下来已经不行了.回来第一件事就是改了项目的一个bug,最近又新增了一个新的 ...

  5. WPF Timeline简易时间轴控件的实现

    原文:WPF Timeline简易时间轴控件的实现 效果图: 由于整个控件是实现之后才写的教程,因此这里记录的代码是最终实现后的,前后会引用到其他的一些依赖属性或者代码,需要阅读整篇文章. 1.确定T ...

  6. android - 自定义(组合)控件 + 自定义控件外观

    转载:http://www.cnblogs.com/bill-joy/archive/2012/04/26/2471831.html android - 自定义(组合)控件 + 自定义控件外观   A ...

  7. WPF自定义控件(一)の控件分类

    一.什么是控件(Controls) 控件是指对数据和方法的封装.控件可以有自己的属性和方法,其中属性是控件数据的简单访问者,方法则是控件的一些简单而可见的功能.控件创建过程包括设计.开发.调试(就是所 ...

  8. Android创建自定义的布局和控件

    Android的自带布局有framelayout.linerlayout.relativelayout,外加两个百分比布局,但是这些无法灵活的满足我们的需要,所以我们要自己自定义并引入自己的布局.首先 ...

  9. WindowsXamlHost:在 WPF 中使用 UWP 的控件(Windows Community Toolkit)

    Windows Community Toolkit 再次更新到 5.0.以前可以在 WPF 中使用有限的 UWP 控件,而现在有了 WindowsXamlHost,则可以使用更多 UWP 原生控件了. ...

随机推荐

  1. java设计模式-----14、桥接模式

    Bridge 模式又叫做桥接模式,是构造型的设计模式之一.Bridge模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任.它的主要特点是把抽象(abstraction ...

  2. java设计模式单例模式 ----懒汉式与饿汉式的区别

    常用的五种单例模式实现方式 ——主要: 1.饿汉式(线程安全,调用率高,但是,不能延迟加载.) 2.懒汉式(线程安全,调用效率不高,可以延时加载.) ——其他: 1.双重检测锁式(由于JVM底层内部模 ...

  3. C++学习-2

    副本机制 lambda不能取地址,无法当作函数指针 [1](2){3}(4)匿名lambda 1捕获列表   =只读    2后加mutable就可以修改副本 &读写              ...

  4. 【python学习笔记】5.条件、循环和其他语句

    [python学习笔记]5.条件.循环和其他语句 print: 用来打印表达式,不管是字符串还是其他类型,都输出以字符串输出:可以通过逗号分隔输出多个表达式 import: 导入模块     impo ...

  5. HashSet实现不重复储值原理-附源码解析

    在HashSet中,基本的操作都是由HashMap底层实现的,因为HashSet底层是用HashMap存储数据.当向HashSet中添加元素的时候,首先计算元素的hashcode值,然后用这个(元素的 ...

  6. Selenium和Firefox兼容问题

    运行时遇到错误: org.openqa.selenium.firefox.NotConnectedException: Unable to connect to host 127.0.0.1 on p ...

  7. android 获取wifi列表,如果你忽略了这个细节,可能你的软件会崩溃

    一:业务描述 最近公司有一个小需求,用户点击wifi扫描按钮(注意:是用户主动点击wifi扫描按钮),app去扫描附近的wifi,显示在listView中,仅此而已,app都不用去连接某个wifi,看 ...

  8. 第一迭代目标——future weather

    第一个迭代目标(主要数据) 引导界面.获取天气数据(api接口).天气分享 人员工作分配: 引导界面:周子静,界面的引导,耗时3天 获取天气数据:包舒婷.俞先浩,api接口,耗时5天 天气分享:郭磊蕾 ...

  9. 可能是最好的SQL入门教程

    个人博客:这可能是最好的SQL入门教程

  10. 【阿里聚安全·安全周刊】500万台Android设备受感染|YouTube封杀枪支组装视频

    本周的七个关键词:  500万Android 设备受感染丨 黑客将矛头指向无线传输协议 丨  YouTube封杀枪支视频 丨 AMD将发布补丁 丨 Gooligan Android 僵尸网络 丨  N ...