diff --git a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/PasswordBoxDemoCtl.xaml b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/PasswordBoxDemoCtl.xaml index f62a047c..fad81202 100644 --- a/src/Shared/HandyControlDemo_Shared/UserControl/Controls/PasswordBoxDemoCtl.xaml +++ b/src/Shared/HandyControlDemo_Shared/UserControl/Controls/PasswordBoxDemoCtl.xaml @@ -6,14 +6,14 @@ Background="{DynamicResource RegionBrush}"> - - + + - + - + diff --git a/src/Shared/HandyControl_Shared/Controls/Attach/PasswordBoxMonitor.cs b/src/Shared/HandyControl_Shared/Controls/Attach/PasswordBoxMonitor.cs index 450613f2..23792d37 100644 --- a/src/Shared/HandyControl_Shared/Controls/Attach/PasswordBoxMonitor.cs +++ b/src/Shared/HandyControl_Shared/Controls/Attach/PasswordBoxMonitor.cs @@ -9,7 +9,7 @@ namespace HandyControl.Controls /// 密码长度 /// public static readonly DependencyProperty PasswordLengthProperty = DependencyProperty.RegisterAttached( - "PasswordLength", typeof(int), typeof(PasswordBoxMonitor), new PropertyMetadata(default(int))); + "PasswordLength", typeof(int), typeof(PasswordBoxMonitor), new PropertyMetadata(ValueBoxes.Int0Box)); public static void SetPasswordLength(DependencyObject element, int value) => element.SetValue(PasswordLengthProperty, value); diff --git a/src/Shared/HandyControl_Shared/Controls/Cover/CoverView/CoverViewContent.cs b/src/Shared/HandyControl_Shared/Controls/Cover/CoverView/CoverViewContent.cs index dfe26dde..eb7f3e8c 100644 --- a/src/Shared/HandyControl_Shared/Controls/Cover/CoverView/CoverViewContent.cs +++ b/src/Shared/HandyControl_Shared/Controls/Cover/CoverView/CoverViewContent.cs @@ -43,7 +43,7 @@ namespace HandyControl.Controls } internal static readonly DependencyProperty ManualHeightProperty = DependencyProperty.Register( - "ManualHeight", typeof(double), typeof(CoverViewContent), new PropertyMetadata(default(double)), value => ValidateHelper.IsInRangeOfPosDouble(value, true)); + "ManualHeight", typeof(double), typeof(CoverViewContent), new PropertyMetadata(ValueBoxes.Double0Box), value => ValidateHelper.IsInRangeOfPosDouble(value, true)); internal double ManualHeight { diff --git a/src/Shared/HandyControl_Shared/Controls/Input/NumericUpDown.cs b/src/Shared/HandyControl_Shared/Controls/Input/NumericUpDown.cs index a22eab01..549f88a5 100644 --- a/src/Shared/HandyControl_Shared/Controls/Input/NumericUpDown.cs +++ b/src/Shared/HandyControl_Shared/Controls/Input/NumericUpDown.cs @@ -232,7 +232,7 @@ namespace HandyControl.Controls /// 最小值 /// public static readonly DependencyProperty MinimumProperty = DependencyProperty.Register( - "Minimum", typeof(double), typeof(NumericUpDown), new PropertyMetadata(default(double), OnMinimumChanged, CoerceMinimum), ArithmeticHelper.IsValidDoubleValue); + "Minimum", typeof(double), typeof(NumericUpDown), new PropertyMetadata(ValueBoxes.Double0Box, OnMinimumChanged, CoerceMinimum), ArithmeticHelper.IsValidDoubleValue); private static void OnMinimumChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { diff --git a/src/Shared/HandyControl_Shared/Controls/Input/PasswordBox.cs b/src/Shared/HandyControl_Shared/Controls/Input/PasswordBox.cs index 2bb0c38f..56c68892 100644 --- a/src/Shared/HandyControl_Shared/Controls/Input/PasswordBox.cs +++ b/src/Shared/HandyControl_Shared/Controls/Input/PasswordBox.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel; +using System.Runtime.InteropServices; using System.Security; using System.Windows; using System.Windows.Controls; @@ -12,10 +13,13 @@ namespace HandyControl.Controls { /// [TemplatePart(Name = ElementPasswordBox, Type = typeof(System.Windows.Controls.PasswordBox))] + [TemplatePart(Name = ElementTextBox, Type = typeof(System.Windows.Controls.TextBox))] public class PasswordBox : Control, IDataInput { private const string ElementPasswordBox = "PART_PasswordBox"; + private const string ElementTextBox = "PART_TextBox"; + /// /// 掩码字符 /// @@ -47,13 +51,22 @@ namespace HandyControl.Controls public static readonly DependencyProperty ShowClearButtonProperty = DependencyProperty.Register( "ShowClearButton", typeof(bool), typeof(PasswordBox), new PropertyMetadata(ValueBoxes.FalseBox)); - private string _password; + public static readonly DependencyProperty ShowEyeButtonProperty = DependencyProperty.Register( + "ShowEyeButton", typeof(bool), typeof(PasswordBox), new PropertyMetadata(ValueBoxes.FalseBox)); + + public static readonly DependencyProperty ShowPasswordProperty = DependencyProperty.Register( + "ShowPassword", typeof(bool), typeof(PasswordBox), + new PropertyMetadata(ValueBoxes.FalseBox, OnShowPasswordChanged)); + + private SecureString _password; private char _passwordChar; + private System.Windows.Controls.TextBox _textBox; + public PasswordBox() { - CommandBindings.Add(new CommandBinding(ControlCommands.Clear, (s, e) => ActualPasswordBox.Clear())); + CommandBindings.Add(new CommandBinding(ControlCommands.Clear, (s, e) => Clear())); } public System.Windows.Controls.PasswordBox ActualPasswordBox { get; set; } @@ -62,14 +75,27 @@ namespace HandyControl.Controls [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string Password { - get => ActualPasswordBox?.Password; + get + { + if (ShowEyeButton && ShowPassword) + { + return _textBox.Text; + } + return ActualPasswordBox?.Password; + } set { if (ActualPasswordBox == null) { - _password = value; + _password = new SecureString(); + if (value == null) + value = string.Empty; + foreach (var item in value) + _password.AppendChar(item); + return; } + ActualPasswordBox.Password = value; } } @@ -83,6 +109,18 @@ namespace HandyControl.Controls set => SetValue(PasswordCharProperty, value); } + public bool ShowEyeButton + { + get => (bool) GetValue(ShowEyeButtonProperty); + set => SetValue(ShowEyeButtonProperty, value); + } + + public bool ShowPassword + { + get => (bool) GetValue(ShowPasswordProperty); + set => SetValue(ShowPasswordProperty, value); + } + public Func> VerifyFunc { get; set; } public bool IsError @@ -115,11 +153,15 @@ namespace HandyControl.Controls if (VerifyFunc != null) { - result = VerifyFunc.Invoke(ActualPasswordBox.Password); + result = VerifyFunc.Invoke(ShowEyeButton && ShowPassword + ? _textBox.Text + : ActualPasswordBox.Password); } else { - if (!string.IsNullOrEmpty(ActualPasswordBox.Password)) + if (!string.IsNullOrEmpty(ShowEyeButton && ShowPassword + ? _textBox.Text + : ActualPasswordBox.Password)) result = OperationResult.Success(); else if (InfoElement.GetNecessary(this)) result = OperationResult.Failed(Lang.IsNecessary); @@ -132,39 +174,95 @@ namespace HandyControl.Controls return result.Data; } + private static void OnShowPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var ctl = (PasswordBox) d; + if (!ctl.ShowEyeButton) return; + if ((bool) e.NewValue) + { + ctl._textBox.Text = ctl.ActualPasswordBox.Password; + ctl._textBox.Select(string.IsNullOrEmpty(ctl._textBox.Text) ? 0 : ctl._textBox.Text.Length, 0); + } + else + { + ctl.ActualPasswordBox.Password = ctl._textBox.Text; + ctl._textBox.Clear(); + } + } + public override void OnApplyTemplate() { if (ActualPasswordBox != null) ActualPasswordBox.PasswordChanged -= PasswordBox_PasswordChanged; + if (_textBox != null) + _textBox.TextChanged -= TextBox_TextChanged; + base.OnApplyTemplate(); ActualPasswordBox = GetTemplateChild(ElementPasswordBox) as System.Windows.Controls.PasswordBox; + _textBox = GetTemplateChild(ElementTextBox) as System.Windows.Controls.TextBox; if (ActualPasswordBox != null) { ActualPasswordBox.PasswordChanged += PasswordBox_PasswordChanged; - if (!string.IsNullOrEmpty(_password)) + if (_password != null) { - ActualPasswordBox.Password = _password; - _password = null; + if (_password.Length > 0) + { + var valuePtr = IntPtr.Zero; + try + { + valuePtr = Marshal.SecureStringToGlobalAllocUnicode(_password); + ActualPasswordBox.Password = Marshal.PtrToStringUni(valuePtr) ?? throw new InvalidOperationException(); + } + finally + { + Marshal.ZeroFreeGlobalAllocUnicode(valuePtr); + _password.Clear(); + } + } } + if (_passwordChar != default(char)) { ActualPasswordBox.PasswordChar = _passwordChar; _passwordChar = default(char); } } + + if (_textBox != null) + { + _textBox.TextChanged += TextBox_TextChanged; + } } - public void Paste() => ActualPasswordBox.Paste(); - - public void SelectAll() => ActualPasswordBox.SelectAll(); - - public void Clear() => ActualPasswordBox.SelectAll(); + public void Paste() + { + ActualPasswordBox.Paste(); + if (ShowEyeButton && ShowPassword) + { + _textBox.Text = ActualPasswordBox.Password; + } + } + public void SelectAll() + { + ActualPasswordBox.SelectAll(); + if (ShowEyeButton && ShowPassword) + { + _textBox.SelectAll(); + } + } + public void Clear() + { + ActualPasswordBox.Clear(); + _textBox.Clear(); + } private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e) => VerifyData(); + + private void TextBox_TextChanged(object sender, TextChangedEventArgs e) => VerifyData(); } } \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Controls/Other/ScrollViewer.cs b/src/Shared/HandyControl_Shared/Controls/Other/ScrollViewer.cs index 533afbb6..8fc34154 100644 --- a/src/Shared/HandyControl_Shared/Controls/Other/ScrollViewer.cs +++ b/src/Shared/HandyControl_Shared/Controls/Other/ScrollViewer.cs @@ -191,7 +191,7 @@ namespace HandyControl.Controls /// 当前垂直滚动偏移 /// private static readonly DependencyProperty CurrentVerticalOffsetProperty = DependencyProperty.Register( - "CurrentVerticalOffset", typeof(double), typeof(ScrollViewer), new PropertyMetadata(default(double), OnCurrentVerticalOffsetChanged)); + "CurrentVerticalOffset", typeof(double), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.Double0Box, OnCurrentVerticalOffsetChanged)); private static void OnCurrentVerticalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { @@ -215,7 +215,7 @@ namespace HandyControl.Controls /// 当前水平滚动偏移 /// public static readonly DependencyProperty CurrentHorizontalOffsetProperty = DependencyProperty.Register( - "CurrentHorizontalOffset", typeof(double), typeof(ScrollViewer), new PropertyMetadata(default(double), OnCurrentHorizontalOffsetChanged)); + "CurrentHorizontalOffset", typeof(double), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.Double0Box, OnCurrentHorizontalOffsetChanged)); private static void OnCurrentHorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { diff --git a/src/Shared/HandyControl_Shared/Controls/StepBar/StepBar.cs b/src/Shared/HandyControl_Shared/Controls/StepBar/StepBar.cs index 3b23b0a0..d14056f4 100644 --- a/src/Shared/HandyControl_Shared/Controls/StepBar/StepBar.cs +++ b/src/Shared/HandyControl_Shared/Controls/StepBar/StepBar.cs @@ -85,7 +85,7 @@ namespace HandyControl.Controls } public static readonly DependencyProperty StepIndexProperty = DependencyProperty.Register( - "StepIndex", typeof(int), typeof(StepBar), new PropertyMetadata(default(int))); + "StepIndex", typeof(int), typeof(StepBar), new PropertyMetadata(ValueBoxes.Int0Box)); public int StepIndex { diff --git a/src/Shared/HandyControl_Shared/Themes/Basic/Geometries.xaml b/src/Shared/HandyControl_Shared/Themes/Basic/Geometries.xaml index 717a1f23..cd561108 100644 --- a/src/Shared/HandyControl_Shared/Themes/Basic/Geometries.xaml +++ b/src/Shared/HandyControl_Shared/Themes/Basic/Geometries.xaml @@ -21,6 +21,8 @@ M716.6003 213.800623c-138.851102-138.915088-364.020238-138.915088-502.935326 0s-138.915088 364.084225 0 502.935326a355.573996 355.573996 0 0 0 502.935326 0 355.573996 355.573996 0 0 0 0-502.935326z m-580.359212 580.359212a465.183184 465.183184 0 1 1 657.783099 0 465.183184 465.183184 0 0 1-657.783099 0z m868.939152 211.156054a63.474789 63.474789 0 0 1-89.837303 0l-89.773316-89.837303a63.410803 63.410803 0 1 1 89.773316-89.773316l89.837303 89.773316a63.346816 63.346816 0 0 1 0 89.837303z M454.464 143.68l-253.44 253.44c-12.032 12.032-12.032 31.36 0 43.392 11.968 11.968 31.36 11.968 43.328 0l237.376-237.376 237.376 237.376c11.968 11.968 31.36 11.968 43.328 0 12.032-12.032 12.032-31.36 0-43.392l-253.44-253.44C491.264 126.016 478.016 124.032 454.464 143.68zM507.968 947.648l252.48-253.376c11.968-11.968 11.968-31.36 0-43.392-11.968-11.968-31.296-11.968-43.264 0l-236.48 237.376L244.16 650.88c-11.968-11.968-31.296-11.968-43.264 0-11.968 12.032-11.968 31.424 0 43.392l252.48 253.376C465.984 960 491.136 964.48 507.968 947.648z M0,4 L10,4 L10,5 L0,5 z + M928 406.4c-100.8-137.6-249.6-224-416-224s-315.2 86.4-416 224c-44.8 60.8-44.8 150.4 0 211.2 102.4 137.6 251.2 224 416 224 166.4 0 315.2-86.4 416-224 46.4-60.8 46.4-150.4 0-211.2zM512 721.6c-115.2 0-209.6-94.4-209.6-209.6 0-115.2 94.4-209.6 209.6-209.6 115.2 0 209.6 94.4 209.6 209.6 1.6 115.2-92.8 209.6-209.6 209.6z m0-360c-83.2 0-150.4 67.2-150.4 150.4s67.2 150.4 150.4 150.4 150.4-67.2 150.4-150.4-67.2-150.4-150.4-150.4z m0 0 + M950.4 361.6c8-20.8 0-43.2-19.2-54.4-9.6-4.8-20.8-6.4-32-3.2s-19.2 11.2-24 22.4c-56 132.8-208 228.8-361.6 228.8-155.2 0-307.2-97.6-363.2-232-4.8-11.2-12.8-19.2-24-24-9.6-4.8-20.8-3.2-32 0-20.8 9.6-30.4 35.2-20.8 56 25.6 60.8 67.2 118.4 123.2 164.8l-67.2 70.4c-14.4 16-14.4 40 0 57.6 8 8 17.6 14.4 28.8 14.4s22.4-3.2 30.4-11.2l76.8-81.6c35.2 20.8 73.6 38.4 113.6 49.6l-28.8 83.2c-8 22.4 3.2 46.4 24 54.4 4.8 1.6 9.6 3.2 14.4 3.2 6.4 0 11.2-1.6 17.6-3.2 9.6-4.8 17.6-12.8 22.4-24l33.6-96c41.6 4.8 81.6 3.2 123.2-3.2l32 94.4c3.2 11.2 11.2 19.2 22.4 24 9.6 4.8 20.8 4.8 32 1.6 20.8-8 32-32 24-54.4l-28.8-84.8c30.4-9.6 59.2-22.4 86.4-38.4l62.4 65.6c14.4 16 43.2 16 57.6 0 16-16 16-43.2 0-60.8l-51.2-54.4c56-43.2 100.8-100.8 128-164.8z M1,3 L1,9 L7,9 L7,3 z M3,1 L3,2 L8,2 L8,7 L9,7 L9,1 z M2,0 L10,0 L10,8 L8,8 L8,10 L0,10 L0,2 L2,2 z M1,1 L1,9 L9,9 L9,1 z M0,0 L10,0 L10,10 L0,10 z M627.52666696 962L550.66666696 890.47999971c116.82-92.99999971 191.09999971-230.94 191.09999971-385.2 0-146.99999971-67.61999971-279-174.96-371.57999942L643.84666667 62C770.86666638 172.99999971 850.66666667 330.2 850.66666667 505.09999971c0 182.27999971-86.58 345.42-223.13999971 456.90000029zM405.64666638 782l-76.32-77.22a227.88 227.88 0 0 0 116.40000058-199.26A228.06 228.06 0 0 0 347.86666638 317.84000029L422.86666696 242A334.37999971 334.37999971 0 0 1 550.66666696 505.52 334.62 334.62 0 0 1 405.64666638 782zM205.66666638 596.6C164.26666638 596.6 130.66666667 562.51999971 130.66666667 520.64 130.66666667 478.76000029 164.26666638 444.79999971 205.66666638 444.79999971s74.99999971 33.95999971 75.00000058 75.90000058c0 41.87999971-33.59999971 75.84000029-75.00000058 75.83999942z diff --git a/src/Shared/HandyControl_Shared/Themes/Styles/Base/PasswordBoxBaseStyle.xaml b/src/Shared/HandyControl_Shared/Themes/Styles/Base/PasswordBoxBaseStyle.xaml index 6c8abed3..6c1948eb 100644 --- a/src/Shared/HandyControl_Shared/Themes/Styles/Base/PasswordBoxBaseStyle.xaml +++ b/src/Shared/HandyControl_Shared/Themes/Styles/Base/PasswordBoxBaseStyle.xaml @@ -9,6 +9,7 @@ +