WPF里TextBox没有placeholder,需要自己实现,本篇博客介绍WPF TextBox实现placeholder,效果如下:
实现技巧是在 TextBox 控件的 Style 中使用触发器(Triggers)来显示和隐藏placeholder文本。xmal代码如下:
<Window x:Class="WpfApp_TextBox.MainWindow"
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:local="clr-namespace:WpfApp_TextBox"
mc:Ignorable="d"
Title="MainWindow" Height="461" Width="837">
<Grid>
<Canvas>
<!--设置placeholder-->
<TextBox x:Name="userName" Width="240" Height="36" FontSize="16" Canvas.Left="20" Canvas.Top="20">
<TextBox.Style>
<Style TargetType="TextBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Grid>
<TextBox x:Name="textSource" Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}}" Background="Transparent" Padding="5"/>
<TextBlock IsHitTestVisible="False" Text="Enter text here..." Foreground="Gray" Padding="5">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Text, Source={x:Reference textSource}}" Value="">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TextBox.Style>
</TextBox>
<!--WPF 中的 TextBox 控件可以设置为自动换行。你可以通过设置 TextBox 的 TextWrapping 属性为 Wrap 来实现这个功能。
当 TextWrapping 属性设置为 Wrap 时, TextWrapping="Wrap", TextBox 会在文本达到边界时自动换行。-->
<TextBox Width="200" Height="80" Canvas.Left="20" Canvas.Top="100"
VerticalScrollBarVisibility="Auto"
TextWrapping="WrapWithOverflow"
AcceptsReturn="True"
ScrollViewer.CanContentScroll="True"/>
<TextBox x:Name="UsernameTextBox" Width="200" Height="30" FontSize="18" VerticalAlignment="Top" HorizontalAlignment="Left" VerticalContentAlignment="Center" Canvas.Left="20" Canvas.Top="220">
<TextBox.Template>
<ControlTemplate TargetType="TextBox">
<Border Background="White" BorderBrush="Gray" BorderThickness="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="/Assets/Images/user.png" Width="20" Height="20" Margin="5,0,0,0" />
<ScrollViewer x:Name="PART_ContentHost" Grid.Column="1" />
<!--这里Margin可以调整文字的位置-->
<TextBlock Grid.Column="1" Text="Enter username..." IsHitTestVisible="False" Foreground="LightGray" Margin="5,2,0,0">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger Binding="{Binding Text, ElementName=UsernameTextBox}" Value="">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
</Border>
</ControlTemplate>
</TextBox.Template>
</TextBox>
<Button Content="Button" HorizontalAlignment="Left" Canvas.Left="20" Canvas.Top="320" VerticalAlignment="Top" Height="41" Width="122" Click="Button_Click"/>
</Canvas>
</Grid>
</Window>
需要注意的是,文本的上下边距,如果有蓝湖设计图写起来会很容易,比如上面代码中,使用Margin调整上边距
Font属性
FontSize="18"
TextBlock的Margin属性
<!--这里Margin可以调整文字的位置-->
<TextBlock Grid.Column="1" Text="Enter username..." IsHitTestVisible="False" Foreground="LightGray" Margin="5,2,0,0">
经过这样调整后placeholder的内容才比能竖直居中显示。