C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > WPF授权码显示密文

WPF实现授权码显示密文并支持换行

作者:WPF开发者

这篇文章主要为大家详细介绍了如何使用WPF实现授权码显示密文并支持换行,文中的示例代码讲解详细,有需要的小伙伴可以参考一下

WPF 授权码显示密文并支持换行

有开发者需要制作一个授权码输入框输入内容后显示密文并且能 Enter 进行换行输入。由于无法使用 PasswordBox 控件本身不支持换行,因为它设计为单行输入控件。

所以最简单的方法是使用 TextBox 并通过自定义逻辑代码来掩盖输入的文本。这样可以实现多行输入,处理文本显示和密码掩码的逻辑。

接下来我们自定义一个控件 MultiLinePasswordBox 继承 TextBox 输入字符会以密码字符(如默认的 )显示。

私有字段如下:

依赖属性如下:

构造函数:

1)MultiLinePasswordBox.cs 代码如下:

using System;
using System.Diagnostics;
using System.Text;
using System.Windows;
using System.Windows.Controls;

namespace WpfTextOrPasswordBox
{
    public class MultiLinePasswordBox : TextBox
    {
        private StringBuilder passwordBuilder = new StringBuilder();
        private string previousText = string.Empty;
        private bool isUpdating = false;

        public char PasswordChar
        {
            get { return (char)GetValue(PasswordCharProperty); }
            set { SetValue(PasswordCharProperty, value); }
        }

        public static readonly DependencyProperty PasswordCharProperty =
            DependencyProperty.Register("PasswordChar", typeof(char), typeof(MultiLinePasswordBox), new PropertyMetadata('●'));


        public string PlainText
        {
            get { return (string)GetValue(PlainTextProperty); }
            set { SetValue(PlainTextProperty, value); }
        }

        public static readonly DependencyProperty PlainTextProperty =
            DependencyProperty.Register("PlainText", typeof(string), typeof(MultiLinePasswordBox), new PropertyMetadata(string.Empty));


        public MultiLinePasswordBox()
        {
            AcceptsReturn = true;
            TextWrapping = TextWrapping.Wrap;
            VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
            TextChanged += PasswordTextBox_TextChanged;
        }

        private void PasswordTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (isUpdating)
                return;

            isUpdating = true;
            var caretIndex = CaretIndex;
            var input = Text;
            if (string.IsNullOrWhiteSpace(Text))
            {
                passwordBuilder.Clear();
            }
            else
            {
                var s = passwordBuilder.Length;
                int lengthDifference = input.Length - previousText.Length;
                if (lengthDifference > 0)
                {
                    var newText = input.Substring(caretIndex - lengthDifference, lengthDifference);
                    passwordBuilder.Insert(caretIndex - lengthDifference, newText);
                }
                else if (lengthDifference < 0)
                {
                    passwordBuilder.Remove(caretIndex, Math.Abs(lengthDifference));
                    if (passwordBuilder[caretIndex - 1].ToString() != input)
                    {
                        var index = passwordBuilder.ToString().IndexOf(passwordBuilder[caretIndex - 1]);
                        passwordBuilder.Replace(passwordBuilder[caretIndex - 1], input.Last());
                    }
                }
                var maskedText = CreateMaskedTextWithLineBreaks(passwordBuilder.ToString());
                TextChanged -= PasswordTextBox_TextChanged;
                Text = maskedText;
                TextChanged += PasswordTextBox_TextChanged;
            }
            previousText = Text;
            CaretIndex = caretIndex;
            PlainText = passwordBuilder.ToString();
            isUpdating = false;
        }

        private string CreateMaskedTextWithLineBreaks(string text)
        {
            var maskedText = new StringBuilder();
            foreach (char c in text)
            {
                if (c == '\r' || c == '\n')
                    maskedText.Append(c);
                else
                    maskedText.Append(PasswordChar.ToString());
            }
            return maskedText.ToString();
        }
    }
}

2)MultiLinePasswordBoxSample.xaml 代码如下:

<wd:Window
    x:Class="WpfTextOrPasswordBox.MultiLinePasswordBoxSample"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WpfTextOrPasswordBox"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"
    Title="MultiLinePasswordBoxSample - WPF开发者"
    Width="800"
    Height="450"
    WindowStartupLocation="CenterScreen"
    mc:Ignorable="d">
    <Grid>
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBlock Margin="0,20">
                <Run Text="明文:" />
                <Run Text="{Binding ElementName=myMultiLinePasswordBox, Path=PlainText}" />
            </TextBlock>
            <local:MultiLinePasswordBox
                x:Name="myMultiLinePasswordBox"
                Width="200"
                Height="60"
                wd:ElementHelper.CornerRadius="3"
                wd:ElementHelper.Watermark="请输入授权码" />
        </StackPanel>
    </Grid>
</wd:Window>

效果图

到此这篇关于WPF实现授权码显示密文并支持换行的文章就介绍到这了,更多相关WPF授权码显示密文内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文