Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some code refactoring, cleanup and fix of #973. #1001

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/Wpf.Ui/Controls/NumberBox/NumberBox.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@
<Grid HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<Border
x:Name="ContentBorder"
MinWidth="{TemplateBinding MinWidth}"
MinHeight="{TemplateBinding MinHeight}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
MinWidth="{TemplateBinding MinWidth}"
MinHeight="{TemplateBinding MinHeight}"
Padding="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Expand All @@ -82,8 +82,8 @@
VerticalAlignment="Top"
Content="{TemplateBinding Icon}"
FontSize="16"
IsTabStop="False"
Foreground="{TemplateBinding Foreground}" />
Foreground="{TemplateBinding Foreground}"
IsTabStop="False" />
<Grid Grid.Column="1" Margin="{TemplateBinding Padding}">
<Decorator
x:Name="PART_ContentHost"
Expand Down Expand Up @@ -116,8 +116,8 @@
Command="{Binding Path=TemplateButtonCommand, RelativeSource={RelativeSource TemplatedParent}}"
CommandParameter="clear"
Cursor="Arrow"
IsTabStop="False"
Foreground="{DynamicResource TextControlButtonForeground}">
Foreground="{DynamicResource TextControlButtonForeground}"
IsTabStop="False">
<controls:Button.Icon>
<controls:SymbolIcon FontSize="{StaticResource NumberBoxButtonIconSize}" Symbol="Dismiss24" />
</controls:Button.Icon>
Expand Down Expand Up @@ -179,8 +179,8 @@
VerticalAlignment="Top"
Content="{TemplateBinding Icon}"
FontSize="16"
IsTabStop="False"
Foreground="{TemplateBinding Foreground}" />
Foreground="{TemplateBinding Foreground}"
IsTabStop="False" />
</Grid>
</Border>
<!-- The Accent Border is a separate element so that changes to the border thickness do not affect the position of the element -->
Expand Down
180 changes: 103 additions & 77 deletions src/Wpf.Ui/Controls/PasswordBox/PasswordBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
// Copyright (C) Leszek Pomianowski and WPF UI Contributors.
// All Rights Reserved.

using System.Diagnostics;
using System.Windows.Controls;
#pragma warning disable SA1124

// ReSharper disable once CheckNamespace
namespace Wpf.Ui.Controls;
Expand All @@ -13,7 +15,7 @@ namespace Wpf.Ui.Controls;
/**
* TextProperty contains asterisks OR raw password if IsPasswordRevealed is set to true
* PasswordProperty always contains raw password
*/
**/

/// <summary>
/// The modified password control.
Expand All @@ -22,56 +24,97 @@ public class PasswordBox : Wpf.Ui.Controls.TextBox
{
private bool _lockUpdatingContents;

/// <summary>
/// Property for <see cref="Password"/>.
/// </summary>
#region Static Properties

/// <summary>Identifies the <see cref="Password"/> dependency property.</summary>
public static readonly DependencyProperty PasswordProperty = DependencyProperty.Register(
nameof(Password),
typeof(string),
typeof(PasswordBox),
new PropertyMetadata(String.Empty, OnPasswordPropertyChanged)
new PropertyMetadata(String.Empty, OnPasswordChanged)
);

/// <summary>
/// Property for <see cref="PasswordChar"/>.
/// </summary>
/// <summary>Identifies the <see cref="PasswordChar"/> dependency property.</summary>
public static readonly DependencyProperty PasswordCharProperty = DependencyProperty.Register(
nameof(PasswordChar),
typeof(char),
typeof(PasswordBox),
new PropertyMetadata('*', OnPasswordCharPropertyChanged)
new PropertyMetadata('*', OnPasswordCharChanged)
);

/// <summary>
/// Property for <see cref="IsPasswordRevealed"/>.
/// </summary>
/// <summary>Identifies the <see cref="IsPasswordRevealed"/> dependency property.</summary>
public static readonly DependencyProperty IsPasswordRevealedProperty = DependencyProperty.Register(
nameof(IsPasswordRevealed),
typeof(bool),
typeof(PasswordBox),
new PropertyMetadata(false, OnPasswordRevealModePropertyChanged)
new PropertyMetadata(false, OnIsPasswordRevealedChanged)
);

/// <summary>
/// Property for <see cref="RevealButtonEnabled"/>.
/// </summary>
/// <summary>Identifies the <see cref="RevealButtonEnabled"/> dependency property.</summary>
public static readonly DependencyProperty RevealButtonEnabledProperty = DependencyProperty.Register(
nameof(RevealButtonEnabled),
typeof(bool),
typeof(PasswordBox),
new PropertyMetadata(true)
);

/// <summary>
/// Event for "Password has changed"
/// </summary>
/// <summary>Identifies the <see cref="PasswordChanged"/> routed event.</summary>
public static readonly RoutedEvent PasswordChangedEvent = EventManager.RegisterRoutedEvent(
nameof(PasswordChanged),
RoutingStrategy.Bubble,
typeof(RoutedEventHandler),
typeof(PasswordBox)
);

/// <summary>
/// Called when <see cref="Password"/> is changed.
/// </summary>
private static void OnPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not PasswordBox control)
{
return;
}

control.OnPasswordChanged();
}

/// <summary>
/// Called if the character is changed in the during the run.
/// </summary>
private static void OnPasswordCharChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e
)
{
if (d is not PasswordBox control)
{
return;
}

control.OnPasswordCharChanged();
}

/// <summary>
/// Called if the reveal mode is changed in the during the run.
/// </summary>
private static void OnIsPasswordRevealedChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e
)
{
if (d is not PasswordBox control)
{
return;
}

control.OnPasswordRevealModeChanged();
}

#endregion

#region Properties

/// <summary>
/// Gets or sets currently typed text represented by asterisks.
/// </summary>
Expand Down Expand Up @@ -100,14 +143,18 @@ public bool IsPasswordRevealed
}

/// <summary>
/// Gets or sets a value deciding whether to display the reveal password button.
/// Gets or sets a value indicating whether to display the reveal password button.
/// </summary>
public bool RevealButtonEnabled
{
get => (bool)GetValue(RevealButtonEnabledProperty);
set => SetValue(RevealButtonEnabledProperty, value);
}

#endregion

#region Public Events

/// <summary>
/// Event fired from this text box when its inner content
/// has been changed.
Expand All @@ -121,10 +168,9 @@ public event RoutedEventHandler PasswordChanged
remove => RemoveHandler(PasswordChangedEvent, value);
}

public PasswordBox()
{
_lockUpdatingContents = false;
}
#endregion

#region Protected Methods

/// <inheritdoc />
protected override void OnTextChanged(TextChangedEventArgs e)
Expand All @@ -137,11 +183,15 @@ protected override void OnTextChanged(TextChangedEventArgs e)
}
else
{
if (PlaceholderEnabled && Text.Length > 0)
PlaceholderEnabled = false;

if (!PlaceholderEnabled && Text.Length < 1)
PlaceholderEnabled = true;
switch (PlaceholderEnabled)
{
case true when Text.Length > 0:
SetCurrentValue(PlaceholderEnabledProperty, false);
break;
case false when Text.Length < 1:
SetCurrentValue(PlaceholderEnabledProperty, true);
break;
}

RevealClearButton();
}
Expand All @@ -163,11 +213,13 @@ protected virtual void OnPasswordCharChanged()
// If password is currently revealed,
// do not replace displayed text with asterisks
if (IsPasswordRevealed)
{
return;
}

_lockUpdatingContents = true;

Text = new String(PasswordChar, Password.Length);
SetCurrentValue(TextProperty, new string(PasswordChar, Password.Length));

_lockUpdatingContents = false;
}
Expand All @@ -176,17 +228,16 @@ protected virtual void OnPasswordRevealModeChanged()
{
_lockUpdatingContents = true;

Text = IsPasswordRevealed ? Password : new String(PasswordChar, Password.Length);
SetCurrentValue(TextProperty, IsPasswordRevealed ? Password : new string(PasswordChar, Password.Length));

_lockUpdatingContents = false;
}

/// <summary>
/// Triggered by clicking a button in the control template.
/// </summary>
/// <param name="sender">Sender of the click event.</param>
/// <param name="parameter">Additional parameters.</param>
protected override void OnTemplateButtonClick(string parameter)
protected override void OnTemplateButtonClick(string? parameter)
{
#if DEBUG
System.Diagnostics.Debug.WriteLine(
Expand All @@ -198,7 +249,7 @@ protected override void OnTemplateButtonClick(string parameter)
switch (parameter)
{
case "reveal":
IsPasswordRevealed = !IsPasswordRevealed;
SetCurrentValue(IsPasswordRevealedProperty, !IsPasswordRevealed);
Focus();
CaretIndex = Text.Length;
break;
Expand All @@ -208,25 +259,33 @@ protected override void OnTemplateButtonClick(string parameter)
}
}

#endregion

#region Private Methods

private void UpdateTextContents(bool isTriggeredByTextInput)
{
if (_lockUpdatingContents)
{
return;
}

if (IsPasswordRevealed)
{
if (Password == Text)
{
return;
}

_lockUpdatingContents = true;

if (isTriggeredByTextInput)
{
Password = Text;
SetCurrentValue(PasswordProperty, Text);
}
else
{
Text = Password;
SetCurrentValue(TextProperty, Password);
CaretIndex = Text.Length;
}

Expand All @@ -248,10 +307,12 @@ private void UpdateTextContents(bool isTriggeredByTextInput)
var newCharacters = currentText.Replace(PasswordChar.ToString(), String.Empty);

if (currentText.Length < currentPassword.Length)
{
newPasswordValue = currentPassword.Remove(
selectionIndex,
currentPassword.Length - currentText.Length
);
}

if (newCharacters.Length > 1)
{
Expand All @@ -264,10 +325,12 @@ private void UpdateTextContents(bool isTriggeredByTextInput)
}
else
{
for (int i = 0; i < currentText.Length; i++)
for (var i = 0; i < currentText.Length; i++)
{
if (currentText[i] == PasswordChar)
{
continue;
}

newPasswordValue =
currentText.Length == newPasswordValue.Length
Expand All @@ -279,51 +342,14 @@ private void UpdateTextContents(bool isTriggeredByTextInput)

_lockUpdatingContents = true;

Text = new String(PasswordChar, newPasswordValue.Length);
Password = newPasswordValue;
SetCurrentValue(TextProperty, new string(PasswordChar, newPasswordValue.Length));
SetCurrentValue(PasswordProperty, newPasswordValue);
CaretIndex = caretIndex;

RaiseEvent(new RoutedEventArgs(PasswordChangedEvent));

_lockUpdatingContents = false;
}

/// <summary>
/// Called when <see cref="Password"/> is changed.
/// </summary>
private static void OnPasswordPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not PasswordBox control)
return;

control.OnPasswordChanged();
}

/// <summary>
/// Called if the character is changed in the during the run.
/// </summary>
private static void OnPasswordCharPropertyChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e
)
{
if (d is not PasswordBox control)
return;

control.OnPasswordCharChanged();
}

/// <summary>
/// Called if the reveal mode is changed in the during the run.
/// </summary>
private static void OnPasswordRevealModePropertyChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e
)
{
if (d is not PasswordBox control)
return;

control.OnPasswordRevealModeChanged();
}
#endregion
}
Loading
Loading