TextBox焦点边框和占位符文本

时间:2017-08-21 11:03:29

标签: wpf textbox focus border placeholder

我想创建一个带占位符文本的文本框,鼠标悬停/焦点时不会变蓝。

Example

通过实验和搜索互联网,我发现以下代码是解决个别问题的最简单方法。

占位符文字

    <Style x:Key="PlaceHolderTextBox" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Grid>
                    <TextBox Text="{Binding Path=Text,
                                            RelativeSource={RelativeSource TemplatedParent}, 
                                            Mode=TwoWay,
                                            UpdateSourceTrigger=PropertyChanged}"
                             x:Name="textSource" 
                             Background="Transparent" 
                             Panel.ZIndex="2" />
                    <TextBox Text="{TemplateBinding Tag}" Background="{TemplateBinding Background}" Panel.ZIndex="1">
                        <TextBox.Style>
                            <Style TargetType="{x:Type TextBox}">
                                <Setter Property="Foreground" Value="Transparent"/>
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding Path=Text, Source={x:Reference textSource}}" Value="">
                                        <Setter Property="Foreground" Value="Gray"/>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </TextBox.Style>
                    </TextBox>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

重点边框替换

    <Style x:Key="CustomBorderTextBox" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                    <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
                </Border>
                <ControlTemplate.Triggers>
                    <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="#000000"/>
                    </Trigger>
                    <Trigger Property="IsFocused" Value="true">
                        <Setter Property="BorderBrush" TargetName="border" Value="Yellow"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

但是,你不能只是将它们结合起来。将网格和边框放在一个ControlTemplate中不起作用,那么如何创建一个替换边框的样式,显示占位符文本(最好没有代码隐藏)?

1 个答案:

答案 0 :(得分:1)

通过添加一个可以有多个孩子的面板(Grid)来组合它们。

我将“CustomBorderTextBox”作为基础,并添加了placehold TextBlock,当文本为空时,它会变为可见。占位符文本存储在TextBox.Tag

<Style x:Key="CustomTextBox" TargetType="{x:Type TextBox}" BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                    <Grid>
                        <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>

                        <TextBlock Text="{TemplateBinding Tag}" IsHitTestVisible="False">
                            <TextBlock.Style>
                                <Style TargetType="TextBlock">
                                    <Setter Property="Visibility" Value="Hidden"/>
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding Path=Text, RelativeSource={RelativeSource AncestorType=TextBox}}" 
                                                     Value="">
                                            <Setter Property="Visibility" Value="Visible"/>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </TextBlock.Style>
                        </TextBlock>

                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <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="#000000"/>
                    </Trigger>
                    <Trigger Property="IsFocused" Value="true">
                        <Setter Property="BorderBrush" TargetName="border" Value="Yellow"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>