From 368fb52ed49a38ccdc477352ca08c8c3d21f82c0 Mon Sep 17 00:00:00 2001
From: NaBian <836904362@qq.com>
Date: Sun, 18 Nov 2018 00:10:10 +0800
Subject: [PATCH] enhance the function of passwordbox
---
HandyControl/Controls/Attach/InfoElement.cs | 4 +-
.../Controls/Attach/PasswordBoxMonitor.cs | 5 +-
HandyControl/Controls/Input/PasswordBox.cs | 172 ++++++++++++
HandyControl/Controls/Input/TextBox.cs | 1 -
HandyControl/HandyControl.csproj | 1 +
.../Styles/Base/PasswordBoxBaseStyle.xaml | 248 +++++++++++++++++-
HandyControl/Themes/Styles/PasswordBox.xaml | 80 +-----
HandyControlDemo/Data/MessageToken.cs | 4 +-
HandyControlDemo/Data/MessageToken.tt | 5 +-
HandyControlDemo/HandyControlDemo.csproj | 13 +-
.../Controls/PasswordBoxDemoCtl.xaml | 20 ++
.../PasswordBoxDemoCtl.xaml.cs | 3 +-
.../UserControl/Main/LeftMainContent.xaml | 7 +-
...oCtl.xaml => NaivePasswordBoxDemoCtl.xaml} | 2 +-
.../Styles/NaivePasswordBoxDemoCtl.xaml.cs | 10 +
15 files changed, 481 insertions(+), 94 deletions(-)
create mode 100644 HandyControl/Controls/Input/PasswordBox.cs
create mode 100644 HandyControlDemo/UserControl/Controls/PasswordBoxDemoCtl.xaml
rename HandyControlDemo/UserControl/{Styles => Controls}/PasswordBoxDemoCtl.xaml.cs (64%)
rename HandyControlDemo/UserControl/Styles/{PasswordBoxDemoCtl.xaml => NaivePasswordBoxDemoCtl.xaml} (95%)
create mode 100644 HandyControlDemo/UserControl/Styles/NaivePasswordBoxDemoCtl.xaml.cs
diff --git a/HandyControl/Controls/Attach/InfoElement.cs b/HandyControl/Controls/Attach/InfoElement.cs
index 088aa1f3..96556197 100644
--- a/HandyControl/Controls/Attach/InfoElement.cs
+++ b/HandyControl/Controls/Attach/InfoElement.cs
@@ -20,7 +20,7 @@ namespace HandyControl.Controls
/// 占位符
///
public static readonly DependencyProperty PlaceholderProperty = DependencyProperty.RegisterAttached(
- "Placeholder", typeof(string), typeof(InfoElement), new PropertyMetadata(default(string)));
+ "Placeholder", typeof(string), typeof(InfoElement), new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.Inherits));
public static void SetPlaceholder(DependencyObject element, string value) => element.SetValue(PlaceholderProperty, value);
@@ -70,7 +70,7 @@ namespace HandyControl.Controls
/// 内容高度
///
public static readonly DependencyProperty ContentHeightProperty = DependencyProperty.RegisterAttached(
- "ContentHeight", typeof(double), typeof(InfoElement), new PropertyMetadata(30.0));
+ "ContentHeight", typeof(double), typeof(InfoElement), new FrameworkPropertyMetadata(30.0, FrameworkPropertyMetadataOptions.Inherits));
public static void SetContentHeight(DependencyObject element, double value) => element.SetValue(ContentHeightProperty, value);
diff --git a/HandyControl/Controls/Attach/PasswordBoxMonitor.cs b/HandyControl/Controls/Attach/PasswordBoxMonitor.cs
index 9c469155..0e78d619 100644
--- a/HandyControl/Controls/Attach/PasswordBoxMonitor.cs
+++ b/HandyControl/Controls/Attach/PasswordBoxMonitor.cs
@@ -1,5 +1,4 @@
using System.Windows;
-using System.Windows.Controls;
using HandyControl.Data;
// ReSharper disable once CheckNamespace
@@ -25,7 +24,7 @@ namespace HandyControl.Controls
private static void OnIsMonitoringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
- if (d is PasswordBox passwordBox)
+ if (d is System.Windows.Controls.PasswordBox passwordBox)
{
if (e.NewValue is bool boolValue)
{
@@ -47,7 +46,7 @@ namespace HandyControl.Controls
private static void PasswordChanged(object sender, RoutedEventArgs e)
{
- if (sender is PasswordBox passwordBox)
+ if (sender is System.Windows.Controls.PasswordBox passwordBox)
{
SetPasswordLength(passwordBox, passwordBox.Password.Length);
}
diff --git a/HandyControl/Controls/Input/PasswordBox.cs b/HandyControl/Controls/Input/PasswordBox.cs
new file mode 100644
index 00000000..22e2168f
--- /dev/null
+++ b/HandyControl/Controls/Input/PasswordBox.cs
@@ -0,0 +1,172 @@
+using System;
+using System.ComponentModel;
+using System.Security;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using HandyControl.Data;
+using HandyControl.Interactivity;
+using HandyControl.Properties.Langs;
+
+namespace HandyControl.Controls
+{
+ ///
+ public class PasswordBox : Control, IDataInput
+ {
+ private const string ElementPasswordBox = "PART_PasswordBox";
+
+ ///
+ /// 掩码字符
+ ///
+ public static readonly DependencyProperty PasswordCharProperty =
+ System.Windows.Controls.PasswordBox.PasswordCharProperty.AddOwner(typeof(PasswordBox),
+ new FrameworkPropertyMetadata('●'));
+
+ ///
+ /// 数据是否错误
+ ///
+ public static readonly DependencyProperty IsErrorProperty = DependencyProperty.Register(
+ "IsError", typeof(bool), typeof(PasswordBox), new PropertyMetadata(default(bool)));
+
+ ///
+ /// 错误提示
+ ///
+ public static readonly DependencyProperty ErrorStrProperty = DependencyProperty.Register(
+ "ErrorStr", typeof(string), typeof(PasswordBox), new PropertyMetadata(default(string)));
+
+ ///
+ /// 文本类型
+ ///
+ public static readonly DependencyProperty TextTypeProperty = DependencyProperty.Register(
+ "TextType", typeof(TextType), typeof(PasswordBox), new PropertyMetadata(default(TextType)));
+
+ ///
+ /// 是否显示清除按钮
+ ///
+ public static readonly DependencyProperty ShowClearButtonProperty = DependencyProperty.Register(
+ "ShowClearButton", typeof(bool), typeof(PasswordBox), new PropertyMetadata(default(bool)));
+
+ private string _password;
+
+ private char _passwordChar;
+
+ public PasswordBox()
+ {
+ CommandBindings.Add(new CommandBinding(ControlCommands.Clear, (s, e) => ActualPasswordBox.Clear()));
+ }
+
+ public System.Windows.Controls.PasswordBox ActualPasswordBox { get; set; }
+
+ [DefaultValue("")]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public string Password
+ {
+ get => ActualPasswordBox?.Password;
+ set
+ {
+ if (ActualPasswordBox == null)
+ {
+ _password = value;
+ return;
+ }
+ ActualPasswordBox.Password = value;
+ }
+ }
+
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
+ public SecureString SecurePassword => ActualPasswordBox?.SecurePassword;
+
+ public char PasswordChar
+ {
+ get => (char) GetValue(PasswordCharProperty);
+ set => SetValue(PasswordCharProperty, value);
+ }
+
+ public Func> VerifyFunc { get; set; }
+
+ public bool IsError
+ {
+ get => (bool) GetValue(IsErrorProperty);
+ set => SetValue(IsErrorProperty, value);
+ }
+
+ public string ErrorStr
+ {
+ get => (string) GetValue(ErrorStrProperty);
+ set => SetValue(ErrorStrProperty, value);
+ }
+
+ public TextType TextType
+ {
+ get => (TextType) GetValue(TextTypeProperty);
+ set => SetValue(TextTypeProperty, value);
+ }
+
+ public bool ShowClearButton
+ {
+ get => (bool) GetValue(ShowClearButtonProperty);
+ set => SetValue(ShowClearButtonProperty, value);
+ }
+
+ public virtual bool VerifyData()
+ {
+ OperationResult result;
+
+ if (VerifyFunc != null)
+ {
+ result = VerifyFunc.Invoke(ActualPasswordBox.Password);
+ }
+ else
+ {
+ if (!string.IsNullOrEmpty(ActualPasswordBox.Password))
+ result = OperationResult.Success();
+ else if (InfoElement.GetNecessary(this))
+ result = OperationResult.Failed(Lang.IsNecessary);
+ else
+ result = OperationResult.Success();
+ }
+
+ IsError = !result.Data;
+ ErrorStr = result.Message;
+ return result.Data;
+ }
+
+ public override void OnApplyTemplate()
+ {
+ if (ActualPasswordBox != null)
+ ActualPasswordBox.PasswordChanged -= PasswordBox_PasswordChanged;
+
+ base.OnApplyTemplate();
+
+ ActualPasswordBox = GetTemplateChild(ElementPasswordBox) as System.Windows.Controls.PasswordBox;
+ if (ActualPasswordBox != null)
+ {
+ ActualPasswordBox.PasswordChanged += PasswordBox_PasswordChanged;
+
+ if (!string.IsNullOrEmpty(_password))
+ {
+ ActualPasswordBox.Password = _password;
+ _password = null;
+ }
+ if (_passwordChar != default(char))
+ {
+ ActualPasswordBox.PasswordChar = _passwordChar;
+ _passwordChar = default(char);
+ }
+ }
+ }
+
+ public void Paste() => ActualPasswordBox.Paste();
+
+ public void SelectAll() => ActualPasswordBox.SelectAll();
+
+ public void Clear() => ActualPasswordBox.SelectAll();
+
+
+
+ private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
+ {
+ VerifyData();
+ }
+ }
+}
\ No newline at end of file
diff --git a/HandyControl/Controls/Input/TextBox.cs b/HandyControl/Controls/Input/TextBox.cs
index 2216919c..abfc12a3 100644
--- a/HandyControl/Controls/Input/TextBox.cs
+++ b/HandyControl/Controls/Input/TextBox.cs
@@ -6,7 +6,6 @@ using HandyControl.Data;
using HandyControl.Interactivity;
using HandyControl.Tools;
-// ReSharper disable once CheckNamespace
namespace HandyControl.Controls
{
///
diff --git a/HandyControl/HandyControl.csproj b/HandyControl/HandyControl.csproj
index dbdfa326..52f78b16 100644
--- a/HandyControl/HandyControl.csproj
+++ b/HandyControl/HandyControl.csproj
@@ -54,6 +54,7 @@
+
diff --git a/HandyControl/Themes/Styles/Base/PasswordBoxBaseStyle.xaml b/HandyControl/Themes/Styles/Base/PasswordBoxBaseStyle.xaml
index 17477ef2..d4148471 100644
--- a/HandyControl/Themes/Styles/Base/PasswordBoxBaseStyle.xaml
+++ b/HandyControl/Themes/Styles/Base/PasswordBoxBaseStyle.xaml
@@ -1,7 +1,16 @@
+ xmlns:controls="clr-namespace:HandyControl.Controls"
+ xmlns:system="clr-namespace:System;assembly=mscorlib"
+ xmlns:interactivity="clr-namespace:HandyControl.Interactivity">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HandyControl/Themes/Styles/PasswordBox.xaml b/HandyControl/Themes/Styles/PasswordBox.xaml
index 2039e0c2..af2c79ba 100644
--- a/HandyControl/Themes/Styles/PasswordBox.xaml
+++ b/HandyControl/Themes/Styles/PasswordBox.xaml
@@ -1,89 +1,15 @@
+ xmlns:controls="clr-namespace:HandyControl.Controls">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/HandyControlDemo/Data/MessageToken.cs b/HandyControlDemo/Data/MessageToken.cs
index b74483b8..bdce5727 100644
--- a/HandyControlDemo/Data/MessageToken.cs
+++ b/HandyControlDemo/Data/MessageToken.cs
@@ -42,6 +42,8 @@
public static readonly string ComboBoxDemoCtl = nameof(ComboBoxDemoCtl);
+ public static readonly string PasswordBoxDemoCtl = nameof(PasswordBoxDemoCtl);
+
public static readonly string ButtonDemoCtl = nameof(ButtonDemoCtl);
public static readonly string ToggleButtonDemoCtl = nameof(ToggleButtonDemoCtl);
@@ -62,7 +64,7 @@
public static readonly string NaiveComboBoxDemoCtl = nameof(NaiveComboBoxDemoCtl);
- public static readonly string PasswordBoxDemoCtl = nameof(PasswordBoxDemoCtl);
+ public static readonly string NaivePasswordBoxDemoCtl = nameof(NaivePasswordBoxDemoCtl);
public static readonly string NaiveTabControlDemoCtl = nameof(NaiveTabControlDemoCtl);
diff --git a/HandyControlDemo/Data/MessageToken.tt b/HandyControlDemo/Data/MessageToken.tt
index 68d36bb8..ec9d74e2 100644
--- a/HandyControlDemo/Data/MessageToken.tt
+++ b/HandyControlDemo/Data/MessageToken.tt
@@ -23,7 +23,8 @@ var controlList = new List
"PreviewSliderDemoCtl",
"CircleProgressBarDemoCtl",
"TextBoxDemoCtl",
- "ComboBoxDemoCtl"
+ "ComboBoxDemoCtl",
+ "PasswordBoxDemoCtl"
};
var styleList = new List
{
@@ -37,7 +38,7 @@ var styleList = new List
"NaiveTextBoxDemoCtl",
"TextBlockDemoCtl",
"NaiveComboBoxDemoCtl",
- "PasswordBoxDemoCtl",
+ "NaivePasswordBoxDemoCtl",
"NaiveTabControlDemoCtl",
"DataGridDemoCtl",
"CheckBoxDemoCtl",
diff --git a/HandyControlDemo/HandyControlDemo.csproj b/HandyControlDemo/HandyControlDemo.csproj
index 63b62b18..3ea8bca5 100644
--- a/HandyControlDemo/HandyControlDemo.csproj
+++ b/HandyControlDemo/HandyControlDemo.csproj
@@ -132,6 +132,9 @@
NumericUpDownDemoCtl.xaml
+
+ PasswordBoxDemoCtl.xaml
+
PreviewSliderDemoCtl.xaml
@@ -207,8 +210,8 @@
NaiveTabControlDemoCtl.xaml
-
- PasswordBoxDemoCtl.xaml
+
+ NaivePasswordBoxDemoCtl.xaml
ProgressBarDemoCtl.xaml
@@ -357,6 +360,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
@@ -457,7 +464,7 @@
Designer
MSBuild:Compile
-
+
Designer
MSBuild:Compile
diff --git a/HandyControlDemo/UserControl/Controls/PasswordBoxDemoCtl.xaml b/HandyControlDemo/UserControl/Controls/PasswordBoxDemoCtl.xaml
new file mode 100644
index 00000000..2765e826
--- /dev/null
+++ b/HandyControlDemo/UserControl/Controls/PasswordBoxDemoCtl.xaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/HandyControlDemo/UserControl/Styles/PasswordBoxDemoCtl.xaml.cs b/HandyControlDemo/UserControl/Controls/PasswordBoxDemoCtl.xaml.cs
similarity index 64%
rename from HandyControlDemo/UserControl/Styles/PasswordBoxDemoCtl.xaml.cs
rename to HandyControlDemo/UserControl/Controls/PasswordBoxDemoCtl.xaml.cs
index 3b7fc40f..8e750253 100644
--- a/HandyControlDemo/UserControl/Styles/PasswordBoxDemoCtl.xaml.cs
+++ b/HandyControlDemo/UserControl/Controls/PasswordBoxDemoCtl.xaml.cs
@@ -1,5 +1,4 @@
-// ReSharper disable once CheckNamespace
-namespace HandyControlDemo.UserControl
+namespace HandyControlDemo.UserControl
{
public partial class PasswordBoxDemoCtl
{
diff --git a/HandyControlDemo/UserControl/Main/LeftMainContent.xaml b/HandyControlDemo/UserControl/Main/LeftMainContent.xaml
index 513a289f..c550f4af 100644
--- a/HandyControlDemo/UserControl/Main/LeftMainContent.xaml
+++ b/HandyControlDemo/UserControl/Main/LeftMainContent.xaml
@@ -65,7 +65,7 @@
-
+
@@ -139,6 +139,11 @@
+
+
+
+
+
diff --git a/HandyControlDemo/UserControl/Styles/PasswordBoxDemoCtl.xaml b/HandyControlDemo/UserControl/Styles/NaivePasswordBoxDemoCtl.xaml
similarity index 95%
rename from HandyControlDemo/UserControl/Styles/PasswordBoxDemoCtl.xaml
rename to HandyControlDemo/UserControl/Styles/NaivePasswordBoxDemoCtl.xaml
index 7ec8b7c3..129568f8 100644
--- a/HandyControlDemo/UserControl/Styles/PasswordBoxDemoCtl.xaml
+++ b/HandyControlDemo/UserControl/Styles/NaivePasswordBoxDemoCtl.xaml
@@ -1,4 +1,4 @@
-