2020/6/23 更新一个更简单的方法,用datatrigger触发器,当textbox文本为空字符串时,将上层的textblock的Visibility设置为Visibility(原本是Collapsed),具体代码如下:
1 <Style x:Key="LoginTextBox" TargetType="TextBox">
2 <Setter Property="Width" Value="200"/>
3 <Setter Property="Height" Value="30"/>
4 <Setter Property="Template">
5 <Setter.Value>
6 <ControlTemplate TargetType="TextBox">
7 <Border BorderBrush="#778899" BorderThickness="1" Background="White" CornerRadius="5">
8 <Grid>
9 <Grid.ColumnDefinitions>
10 <ColumnDefinition Width="1*"/>
11 <ColumnDefinition Width="6*"/>
12 </Grid.ColumnDefinitions>
13 <Border Grid.Column="0" BorderBrush="#778899" BorderThickness="0,0,1,0" Margin="0,5,5,5"/>
14 <TextBox x:Name="InputTextBox" Text="" Grid.Column="1" Margin="2,0" FontSize="10" BorderBrush="{x:Null}"
15 VerticalAlignment="Center" BorderThickness="0"/>
16 <TextBlock x:Name="TipTextBlock" Text="请输入用户名" Grid.Column="1" Margin="2,0" FontSize="10" Foreground="#DCDCDC"
17 Visibility="Collapsed" VerticalAlignment="Center" IsHitTestVisible="False"/>
18 </Grid>
19 </Border>
20 <ControlTemplate.Triggers>
21 <DataTrigger Binding="{Binding ElementName=InputTextBox,Path=Text}" Value="">
22 <Setter TargetName="TipTextBlock" Property="Visibility" Value="Visible"/>
23 </DataTrigger>
24 </ControlTemplate.Triggers>
25 </ControlTemplate>
26 </Setter.Value>
27 </Setter>
28 </Style>
原文:
比如说用户界面的输入文本框
主要实现的行为:
1.界面打开的时候有提示文本
2.点击文本框时,提示文字消失
3. 删除输入的文字后,重新显示提示文本
由于最近学习的是MVVM框架的内容,所以想着要把前后台的代码耦合度尽量降低,因此逻辑会相对复杂一点点(对我这样的初学者而言)
主要实现逻辑要点:
1. TextBlock+TextBox,叠加方式,前者提示文本,后者输入文本
(偶然发现,两个控件哪个在上面会导致不同的结果,所以如果改变顺序的话,以下的逻辑需要重新设计)
2.用TextBox触发器,实现=>点击文本框时(键盘焦点),提示文本“隐藏”(将TextBox的背景设置为White,这里TextBox默认背景为transparent, 所以实际上是TextBox覆盖了TextBlock)
3.用数据绑定的方式,将TextBlock的文本绑定到一个属性上,然后用通知更改的方式实现文本内容的转换(从“ 提示文本 ” 到 “ 无文本 ” ,从 “ 无文本 ” 到 “ 提示文本 ” )
更多细节在下面的整体实现过程中:
1.新建Style
(1.1)触发器:当获取到键盘焦点为true时,将属性Background更改为White
(1.2)这里要把TextBox的默认背景设置为Transparent,如果不在Style里面设置,反而在Grid里面建立控件时候在设置的话,触发器无法改变Background
大佬原话 : 触发器触发时要修改的值若不是控件的默认值,就必须在样式中定义,否则触发没效果。
这里主要两个点,一个是Foreground,设置成灰色,看起来才像是提示文本,一个是IsHitTestVisible为False,简单说就是只能看不能点,点击的时候无视当前的控件,所以会作用于下方的控件
2.各自引用Style、各自绑定Text
3.在ViewModel文件中定义与Text绑定的字段
顾名思义,上面图片中的字段是账号文本,也就是输入账号的文本框控件的文本属性
当get的时候,先判断该字段是否为空,是的话就将TipTBtext赋值,具体作用是当我们完全删除输入的内容时,让提示文本重新显示,
当set的时候,也就是说完成输入之后,将TipTBtext赋空值,这样在当前文本框失去键盘焦点时,TipTBtext的值不会和输入值重叠,产生干扰
当然,还需要对TipTBtext设置通知更改,才能实现上述get,set的内容
上图的字段是提示文本,在set的时候设置通知更改
4. ViewModel文件构造函数里面给字段赋值
5.
到这里就完成了,当我们打开该界面的时候,TextBox是透明的,显示了TextBlock,这时候TextBlock上面是初值;
当我们点击输入框的时候,由于TextBlock的IsHitTestVisible属性,我们实际点击到的是TextBox,这时候TextBox获取到键盘焦点,触发器启动,将背景设置为白色,
将TextBlock覆盖了(原因不详);
当我们输入完成后,通过通知更改的功能,将TextBlock上的提示文本,改成空白文本,这样一来,当TextBox不再有键盘焦点的时候,TextBox重新变成透明,也不会发生文本重叠;
当我们完全删除输入的文本后,通过通知更改的功能,将TextBlock上的空白文本重新改成提示文本,重新显示。
大致逻辑就是这样,可能会有一些多余的操作,当然也有更好更方便更快的方法,可以的话指点指点。
这里只是记录学习过程中的一些想法~~~~