WPF TextBox实现placeholder

WPF里TextBox没有placeholder,需要自己实现,本篇博客介绍WPF TextBox实现placeholder,效果如下:

实现技巧是在 TextBox 控件的 Style 中使用触发器(Triggers)来显示和隐藏placeholder文本。xmal代码如下:

xml 复制代码
<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属性

xml 复制代码
FontSize="18"

TextBlock的Margin属性

xml 复制代码
<!--这里Margin可以调整文字的位置-->
<TextBlock Grid.Column="1" Text="Enter username..." IsHitTestVisible="False" Foreground="LightGray" Margin="5,2,0,0">

经过这样调整后placeholder的内容才比能竖直居中显示。

相关推荐
芝麻科技14 小时前
使用ValueConverters扩展实现枚举控制页面的显示
wpf·prism
笑非不退1 天前
Wpf Image 展示方式 图片处理 显示
开发语言·javascript·wpf
△曉風殘月〆2 天前
在WPF中实现多语言切换的四种方式
wpf·多语言切换
笑非不退2 天前
WPF C# 读写嵌入的资源 JSON PNG JPG JPEG 图片等资源
c#·wpf
He BianGu2 天前
演示:基于WPF的DrawingVisual开发的频谱图和律动图
wpf·示波器·曲线图·频谱分析仪·频谱图·高性能曲线·自绘
笑非不退5 天前
WPF 设计属性 设计页面时实时显示 页面涉及集合时不显示处理 设计页面时显示集合样式 显示ItemSource TabControl等集合样式
wpf
△曉風殘月〆6 天前
WPF中的XAML详解
wpf·xaml
ithouse6 天前
使用WPF实现一个快速切换JDK版本的客户端工具
java·开发语言·wpf
河西石头6 天前
WPF之UI进阶--控件样式与样式模板及词典
ui·wpf·样式·模板·控件样式·样式模板·样式词典
TA远方6 天前
【WPF】桌面程序开发之窗口的用户控件详解
c#·wpf·usercontrol·用户控件·控件属性