文本框(TextBox)水印效果
顯示效果:

唯一原文鏈接:https://www.cnblogs.com/kongw/p/10744060.html
方法一:驗證觸發器填充VisualBrush
創建一個可視畫刷VisualBrush,使用觸發器驗證一下Text是否為空,使用VisualBrush填充TextBox的背景色
<TextBox Height="25" Width="180" HorizontalAlignment="Center" Margin="0 50 0 0">
<TextBox.Resources>
<VisualBrush x:Key="HelpBrush" TileMode="None" Opacity="0.3" Stretch="None" AlignmentX="Left">
<VisualBrush.Visual>
<TextBlock Text="請輸入賬號"/>
</VisualBrush.Visual>
</VisualBrush>
</TextBox.Resources>
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Text" Value="">
<Setter Property="Background" Value="{StaticResource HelpBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
方法二:判斷鼠標焦點填充SolidColorBrush
判斷TextBox獲取到焦點時文字消失,失去焦點時文字顯示,在后台使用SolidColorBrush畫刷填充
XAML代碼(添加TextBox獲取到焦點和失去焦點的事件):
<TextBox Name="tbxUser" GotFocus="TbxUser_GotFocus" Foreground="LightGray" LostFocus="TbxUser_LostFocus"
Height="25" Width="180" HorizontalAlignment="Center" Margin="0 20 0 0"></TextBox>
后台代碼(由於窗口剛加載時沒有判斷焦點,所以在窗口加載時初始化填充,然后判斷捕捉到鼠標焦點時取消填充,失去焦點時判斷是否輸入了文字,沒輸入則再次填充):
public MainWindow()
{
InitializeComponent();
tbxUser.Text = "請輸入賬號";
SolidColorBrush scb = new SolidColorBrush(Colors.LightGray);
tbxUser.Foreground = scb;
}
private void TbxUser_GotFocus(object sender, RoutedEventArgs e)
{
tbxUser.Text = "";
SolidColorBrush scb = new SolidColorBrush(Colors.Black);
tbxUser.Foreground = scb;
}
private void TbxUser_LostFocus(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(tbxUser.Text))
{
tbxUser.Text = "請輸入賬號";
SolidColorBrush scb = new SolidColorBrush(Colors.LightGray);
tbxUser.Foreground = scb;
}
}
兩種方法的區別在於第一種鼠標點擊TextBox時提示文字不會消失,當輸入文字時才消失,第二種方法則是鼠標點擊TextBox時則提示文字消失
密碼框(PasswordBox)水印效果
顯示效果:

由於密碼框沒有可以用於判斷輸入值非空的依賴屬性,於是我們添加一個PasswordBoxMonitor類來監測密碼框是否為空,繼承與DependencyObject類;通過PasswordLength屬性來判斷密碼框輸入的內容長度是否為0來顯示水印
需要引入的命名空間:
using System.Windows;
using System.Windows.Controls;
PasswordBoxMonitor類代碼:
public class PasswordBoxMonitor : DependencyObject
{
public static bool GetIsMonitoring(DependencyObject obj)
{
return (bool)obj.GetValue(IsMonitoringProperty);
}
public static void SetIsMonitoring(DependencyObject obj, bool value)
{
obj.SetValue(IsMonitoringProperty, value);
}
public static readonly DependencyProperty IsMonitoringProperty =
DependencyProperty.RegisterAttached("IsMonitoring", typeof(bool), typeof(PasswordBoxMonitor), new UIPropertyMetadata(false, OnIsMonitoringChanged));
public static int GetPasswordLength(DependencyObject obj)
{
return (int)obj.GetValue(PasswordLengthProperty);
}
public static void SetPasswordLength(DependencyObject obj, int value)
{
obj.SetValue(PasswordLengthProperty, value);
}
public static readonly DependencyProperty PasswordLengthProperty =
DependencyProperty.RegisterAttached("PasswordLength", typeof(int), typeof(PasswordBoxMonitor), new UIPropertyMetadata(0));
private static void OnIsMonitoringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var pb = d as PasswordBox;
if (pb == null)
{
return;
}
if ((bool)e.NewValue)
{
pb.PasswordChanged += PasswordChanged;
}
else
{
pb.PasswordChanged -= PasswordChanged;
}
}
static void PasswordChanged(object sender, RoutedEventArgs e)
{
var pb = sender as PasswordBox;
if (pb == null)
{
return;
}
SetPasswordLength(pb, pb.Password.Length);
}
}
創建好類之后再使用重構的PasswordBox,需要在window中引用
xmlns:PasswordStyle="clr-namespace:你的項目名"
之后在PasswordBox樣式中重寫ControlTemplate 方法,添加一個TextBox覆蓋掉密碼框,當輸入文字之后隱藏掉TextBox
XAML代碼:
<PasswordBox VerticalAlignment="Center" Name="pb" HorizontalAlignment="Center"
VerticalContentAlignment="Center" Height="30" Width="220"
Margin="0 10 0 0">
<PasswordBox.Style>
<Style TargetType="PasswordBox">
<Setter Property="Height" Value="23"></Setter>
<Setter Property="HorizontalAlignment" Value="Left"></Setter>
<Setter Property="VerticalAlignment" Value="Top"></Setter>
<Setter Property="PasswordStyle:PasswordBoxMonitor.IsMonitoring" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type PasswordBox}">
<Border Name="Bd" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="true">
<Grid>
<ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
<StackPanel Orientation="Horizontal" Visibility="Collapsed" Name="myStackPanel">
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Foreground="LightGray" Text=" 請輸入密碼"/>
</StackPanel>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Visibility" TargetName="myStackPanel" Value="Collapsed"/>
</Trigger>
<Trigger Property="PasswordStyle:PasswordBoxMonitor.PasswordLength" Value="0">
<Setter Property="Visibility" TargetName="myStackPanel" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</PasswordBox.Style>
</PasswordBox>
提示:寫完之后可能會提示命名空間找不到,有時候是編譯器沒刷新過來,嘗試編譯運行一下就好了
♪(^∀^●)ノ
