• c#笔记--WPF文本框和密码框添加水印效果(背景文字提示)


    文本框(TextBox)水印效果

    显示效果:

    方法一:验证触发器填充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>
    

    提示:写完之后可能会提示命名空间找不到,有时候是编译器没刷新过来,尝试编译运行一下就好了
    ♪(^∀^●)ノ

  • 相关阅读:
    工作交接
    .NET 利用反射将对象数据添加到数据库
    【C#】IPAddress.Any 解决本地ip和服务器ip切换问题
    【C#】警告System.Configuration.ConfigurationSettings.AppSettings" 已过时
    【C#】TcpListener的对象“已过时”的编译警告
    大城小胖这几年积累的动画库、手势库、物理引擎库
    select option项选择后跳转页面
    360引起的Soap的java.io.EOFException错误
    linux安装mysql-5.7.22与数据自动备份
    性能测试流程
  • 原文地址:https://www.cnblogs.com/zhaiganggang/p/15216338.html
Copyright © 2020-2023  润新知