前言
本文将详细介绍如何在WPF中创建一个自定义的TextBox控件,该控件不仅支持水印提示,还允许设置圆角边框。
通过本文的学习,大家将掌握如何扩展WPF控件以满足特定需求。
正文
设置水印 TextBox 控件
简单设置水印TextBox控件,废话不多说看代码:
xml
<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需要设置圆角。这个时候就需要添加自定义控件,添加依赖属性来扩展功能了。
1、添加自定义控件TextBoxEx
代码如下:
cs
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(234,234,234))));
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(79,173,216))));
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(106,103,90))));
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(106,103,90)));
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(0)));
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、设置TextBoxEx样式
xml
<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转换器的使用大家可以百度。
转换器的内容如下:
cs
public class CornerRadiusToThickness : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Thickness result = new Thickness(0);
if (value is CornerRadius)
{
var tem = (CornerRadius)value;
result = new Thickness(tem.TopLeft, 0, tem.TopRight, 0);
}
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"
3、引用方法
xml
<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:github.com/cmfGit/WpfD...
关键词
WPF、自定义控件、TextBox、水印提示、圆角边框、用户体验、控件开发、附加属性、样式模板
最后
如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。
也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!
优秀是一种习惯,欢迎大家留言学习!
作者:一叶知秋,知寒冬
出处:cnblogs.com/pumbaa/p/14736311.html
声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!