using System.Diagnostics; namespace WPFluent.Controls; public partial class PasswordBox { private class PasswordHelper { private string currentPassword; private string currentText; private string newPasswordValue; private readonly PasswordBox passwordBox; public PasswordHelper(PasswordBox passwordBox) { this.passwordBox = passwordBox; currentText = string.Empty; newPasswordValue = string.Empty; currentPassword = string.Empty; } private bool IsDeleteOption() { Debug.Assert(currentText == passwordBox.Text, "_currentText == _passwordBox.Text"); Debug.Assert(currentPassword == passwordBox.Password, "_currentPassword == _passwordBox.Password"); return currentText.Length < currentPassword.Length; } private void UpdatePasswordWithInputCharacter(int insertIndex, string insertValue) { Debug.Assert(currentText == passwordBox.Text, "_currentText == _passwordBox.Text"); if(currentText.Length == newPasswordValue.Length) { // If it's a direct character replacement, remove the existing one before inserting the new one. newPasswordValue = newPasswordValue.Remove(insertIndex, 1).Insert(insertIndex, insertValue); } else { newPasswordValue = newPasswordValue.Insert(insertIndex, insertValue); } } public string GetNewPassword() { currentPassword = GetPassword(); newPasswordValue = currentPassword; currentText = passwordBox.Text; var selectionIndex = passwordBox.SelectionStart; var passwordChar = passwordBox.PasswordChar; var newCharacters = currentText.Replace(passwordChar.ToString(), string.Empty); bool isDeleted = false; if(IsDeleteOption()) { newPasswordValue = currentPassword.Remove(selectionIndex, currentPassword.Length - currentText.Length); isDeleted = true; } switch(newCharacters.Length) { case > 1: { var index = currentText.IndexOf(newCharacters[0]); newPasswordValue = index > newPasswordValue.Length - 1 ? $"{newPasswordValue}{newCharacters}" : newPasswordValue.Insert(index, newCharacters); break; } case 1: { for(int i = 0; i < currentText.Length; i++) { if(currentText[i] == passwordChar) { continue; } UpdatePasswordWithInputCharacter(i, currentText[i].ToString()); break; } break; } case 0 when !isDeleted: { // The input is a PasswordChar, which is to be inserted at the designated position. int insertIndex = selectionIndex - 1; UpdatePasswordWithInputCharacter(insertIndex, passwordChar.ToString()); break; } } return newPasswordValue; } public string GetPassword() => passwordBox.Password ?? string.Empty; } }