WPF實現授權碼顯示密文并支持換行
WPF 授權碼顯示密文并支持換行
- 框架使用
.NET8; Visual Studio 2022;
有開發(fā)者需要制作一個授權碼輸入框輸入內容后顯示密文并且能 Enter 進行換行輸入。由于無法使用 PasswordBox 控件本身不支持換行,因為它設計為單行輸入控件。
所以最簡單的方法是使用 TextBox 并通過自定義邏輯代碼來掩蓋輸入的文本。這樣可以實現多行輸入,處理文本顯示和密碼掩碼的邏輯。
接下來我們自定義一個控件 MultiLinePasswordBox 繼承 TextBox 輸入字符會以密碼字符(如默認的 ● )顯示。
私有字段如下:
- passwordBuilder 用于存儲密碼。
- previousText 用于存放上一次的文本。
- isUpdating 用于記錄是否正在編輯。
依賴屬性如下:
- PasswordChar:用于顯示密碼字符的字符,如果未顯示則默認為
●。 - PlainText:控件中原始的未掩蓋的文本。
構造函數:
- 設置 TextWrapping = TextWrapping.Wrap; 支持多行顯示。
- 設置 AcceptsReturn = true 支持按下
Enter換行。 - 訂閱 TextChanged 事件,文本更改時將輸入的文本轉換為密碼掩碼,如果 isUpdating 的標志為 true ,則直接返回,避免重復更新文本。
- 計算當前輸入文本和上一次文本之間的長度差異,如果長度是正數則插入,反之長度差異是負數則刪除。
- 調用 CreateMaskedTextWithLineBreaks 方法創(chuàng)建帶有掩碼和換行符的文本。
- 更新控件的文本,保持光標位置不變,并更新PlainText。
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開發(fā)者"
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授權碼顯示密文內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C# 使用multipart form-data方式post數據到服務器
這篇文章主要介紹了C# 使用multipart form-data方式post數據到服務器,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08

