You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF实现点击眼睛按钮切换PasswordBox密码可见性的方法

密码框显示/隐藏切换功能修复方案

需求:点击密码输入框右侧眼睛按钮时,显示明文密码并切换为闭眼图标;再次点击隐藏密码,切换回睁眼图标。现有代码存在问题,以下是修正方案:

现有代码问题分析

  1. 切换按钮未绑定点击事件,无法触发状态切换逻辑
  2. XAML中缺少明文显示用的TextBox控件,但C#代码中直接引用了该控件
  3. 图标未根据密码可见状态自动切换资源
  4. 未处理密码框与明文输入框的文本同步问题

修正后的XAML代码

<Grid Width="419">
    <!-- 密码输入框 -->
    <PasswordBox x:Name="PasswordBox" Width="419" Height="42" 
                 Margin="0,5,0,0"
                 materialDesign:HintAssist.Hint=" Пароль" 
                 Foreground="#848386" 
                 FontSize="14" 
                 materialDesign:HintAssist.FontFamily="{StaticResource Vela Sans M}" 
                 HorizontalAlignment="Center" 
                 Padding="10,0,0,2"
                 Background="Transparent" VerticalAlignment="Center"/>
    <!-- 明文显示输入框,默认隐藏 -->
    <TextBox x:Name="PasswordTextBox" Width="419" Height="42" 
             Margin="0,5,0,0"
             materialDesign:HintAssist.Hint=" Пароль" 
             Foreground="#848386" 
             FontSize="14" 
             materialDesign:HintAssist.FontFamily="{StaticResource Vela Sans M}" 
             HorizontalAlignment="Center" 
             Padding="10,0,0,2"
             Background="Transparent" VerticalAlignment="Center"
             Visibility="Collapsed"/>
    <!-- 状态切换按钮 -->
    <Button Background="Transparent" Width="30" Height="40" HorizontalAlignment="Right" 
            BorderBrush="Transparent" Padding="0 0 10 0" Margin="0 0 0 0"
            Click="TogglePasswordVisibility_Click">
        <Image Width="18" Height="18" Margin="0 0 -10 0">
            <Image.Style>
                <Style TargetType="Image">
                    <!-- 默认显示睁眼图标 -->
                    <Setter Property="Source" Value="{StaticResource eye}"/>
                    <!-- 密码可见时切换为闭眼图标 -->
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsPasswordVisible}" Value="True">
                            <Setter Property="Source" Value="{StaticResource eyeClosed}"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Image.Style>
        </Image>
    </Button>
</Grid>

修正后的C#代码

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private bool _isPasswordVisible;

    public bool IsPasswordVisible
    {
        get => _isPasswordVisible;
        set
        {
            if (_isPasswordVisible != value)
            {
                _isPasswordVisible = value;
                OnPropertyChanged();
            }
        }
    }

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        IsPasswordVisible = false;

        // 同步密码框与明文输入框的文本内容
        PasswordBox.PasswordChanged += (s, e) =>
        {
            if (!IsPasswordVisible)
                PasswordTextBox.Text = PasswordBox.Password;
        };
        PasswordTextBox.TextChanged += (s, e) =>
        {
            if (IsPasswordVisible)
                PasswordBox.Password = PasswordTextBox.Text;
        };
    }

    private void TogglePasswordVisibility_Click(object sender, RoutedEventArgs e)
    {
        IsPasswordVisible = !IsPasswordVisible;

        if (IsPasswordVisible)
        {
            PasswordTextBox.Text = PasswordBox.Password;
            PasswordTextBox.Visibility = Visibility.Visible;
            PasswordBox.Visibility = Visibility.Collapsed;
            // 切换后自动聚焦明文输入框,保持输入状态
            PasswordTextBox.Focus();
            PasswordTextBox.CaretIndex = PasswordTextBox.Text.Length;
        }
        else
        {
            PasswordBox.Password = PasswordTextBox.Text;
            PasswordTextBox.Visibility = Visibility.Collapsed;
            PasswordBox.Visibility = Visibility.Visible;
            // 切换后自动聚焦密码框
            PasswordBox.Focus();
            PasswordBox.CaretIndex = PasswordBox.Password.Length;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

关键修改说明

  1. 添加了明文显示用的TextBox控件,与PasswordBox布局保持一致
  2. 给切换按钮绑定点击事件,关联状态切换逻辑
  3. 使用DataTrigger自动根据IsPasswordVisible状态切换图标(需确保资源字典中存在eye和eyeClosed两个图标资源)
  4. 添加文本同步逻辑,避免切换状态时丢失输入内容
  5. 切换后自动聚焦对应输入框,提升用户操作连贯性

内容的提问来源于stack exchange,提问作者RoDeZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 17:34:52