104 lines
3.5 KiB
C#
104 lines
3.5 KiB
C#
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;
|
|
}
|
|
}
|