ZPasswordBox.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. using CustomUI.MyControls.Primitives;
  2. using System.ComponentModel;
  3. using System.Text;
  4. using System.Windows;
  5. using System.Windows.Controls;
  6. using System.Windows.Controls.Primitives;
  7. using System.Windows.Input;
  8. namespace CustomUI
  9. {
  10. public class ZPasswordBox : IconTextBoxBase
  11. {
  12. #region private fields
  13. private ToggleButton PART_SeePassword;
  14. /// <summary>
  15. /// 该属性是为了防止明文转化为密文后,设置Text时,再次触发Text_Changed事件
  16. /// </summary>
  17. private bool mIsHandledTextChanged = true;
  18. private StringBuilder mPasswordBuilder;
  19. #endregion
  20. #region DependencyProperty
  21. #region IsCanSeePassword
  22. /// <summary>
  23. /// 获取或者设置是否能看见密码
  24. /// </summary>
  25. [Bindable(true), Description("获取或者设置是否能看见密码")]
  26. public bool IsCanSeePassword
  27. {
  28. get { return (bool)GetValue(IsCanSeePasswordProperty); }
  29. set { SetValue(IsCanSeePasswordProperty, value); }
  30. }
  31. public static readonly DependencyProperty IsCanSeePasswordProperty =
  32. DependencyProperty.Register("IsCanSeePassword", typeof(bool), typeof(ZPasswordBox), new PropertyMetadata(true, IsCanSeePasswordChangedCallback));
  33. private static void IsCanSeePasswordChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
  34. {
  35. ZPasswordBox passowrdBox = d as ZPasswordBox;
  36. if(passowrdBox != null && passowrdBox.PART_SeePassword != null)
  37. {
  38. passowrdBox.PART_SeePassword.Visibility = (bool)e.NewValue ? Visibility.Visible : Visibility.Collapsed;
  39. }
  40. }
  41. #endregion
  42. #region Password
  43. /// <summary>
  44. /// 获取或者设置当前密码值
  45. /// </summary>
  46. [Bindable(true), Description("获取或者设置当前密码值")]
  47. public string Password
  48. {
  49. get { return (string)GetValue(PasswordProperty); }
  50. set { SetValue(PasswordProperty, value); }
  51. }
  52. public static readonly DependencyProperty PasswordProperty =
  53. DependencyProperty.Register("Password", typeof(string), typeof(ZPasswordBox), new PropertyMetadata(string.Empty));
  54. #endregion
  55. #region PasswordChar
  56. /// <summary>
  57. /// 获取或者设置PasswordBox的屏蔽字符
  58. /// </summary>
  59. [Bindable(true), Description("获取或者设置PasswordBox的屏蔽字符")]
  60. public char PasswordChar
  61. {
  62. get { return (char)GetValue(PasswordCharProperty); }
  63. set { SetValue(PasswordCharProperty, value); }
  64. }
  65. public static readonly DependencyProperty PasswordCharProperty =
  66. DependencyProperty.Register("PasswordChar", typeof(char), typeof(ZPasswordBox), new PropertyMetadata('●'));
  67. #endregion
  68. #endregion
  69. #region Private DependencyProperty
  70. #region ShowPassword
  71. public bool ShowPassword
  72. {
  73. get { return (bool)GetValue(ShowPasswordProperty); }
  74. private set { SetValue(ShowPasswordProperty, value); }
  75. }
  76. public static readonly DependencyProperty ShowPasswordProperty =
  77. DependencyProperty.Register("ShowPassword", typeof(bool), typeof(ZPasswordBox), new PropertyMetadata(false, ShowPasswordChanged));
  78. private static void ShowPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  79. {
  80. ZPasswordBox passwordBox = d as ZPasswordBox;
  81. if(passwordBox != null)
  82. {
  83. passwordBox.SelectionStart = passwordBox.Text.Length + 1;
  84. }
  85. }
  86. #endregion
  87. #endregion
  88. #region Constructors
  89. static ZPasswordBox()
  90. {
  91. DefaultStyleKeyProperty.OverrideMetadata(typeof(ZPasswordBox), new FrameworkPropertyMetadata(typeof(ZPasswordBox)));
  92. }
  93. #endregion
  94. #region Override
  95. public override void OnApplyTemplate()
  96. {
  97. base.OnApplyTemplate();
  98. this.PART_SeePassword = this.GetTemplateChild("PART_SeePassword") as ToggleButton;
  99. if(this.PART_SeePassword != null)
  100. {
  101. this.PART_SeePassword.Visibility = this.IsCanSeePassword ? Visibility.Visible : Visibility.Collapsed;
  102. }
  103. this.SetEvent();
  104. //回显密码
  105. this.SetText(this.ConvertToPasswordChar(this.Password.Length));
  106. //密码框禁止复制
  107. this.CommandBindings.Add(new System.Windows.Input.CommandBinding(ApplicationCommands.Copy, CommandBinding_Executed, CommandBinding_CanExecute));
  108. }
  109. public override void OnCornerRadiusChanged(CornerRadius newValue)
  110. {
  111. //根据密码框边框圆角自动设置图标背景框圆角
  112. this.IconCornerRadius = new CornerRadius(newValue.TopLeft, 0, 0, newValue.BottomLeft);
  113. }
  114. #endregion
  115. #region private function
  116. private void SetEvent()
  117. {
  118. this.TextChanged += ZPasswordBox_TextChanged;
  119. if(this.PART_SeePassword != null)
  120. {
  121. this.PART_SeePassword.Checked += (o, e) =>
  122. {
  123. this.SetText(this.Password);
  124. this.ShowPassword = true;
  125. };
  126. this.PART_SeePassword.Unchecked += (o, e) =>
  127. {
  128. this.SetText(this.ConvertToPasswordChar(this.Password.Length));
  129. this.ShowPassword = false;
  130. };
  131. }
  132. }
  133. private void SetText(string str)
  134. {
  135. this.mIsHandledTextChanged = false;
  136. this.Text = str;
  137. this.mIsHandledTextChanged = true;
  138. }
  139. /// <summary>
  140. /// 明文密码转化为特定字符
  141. /// </summary>
  142. /// <param name="length"></param>
  143. /// <returns></returns>
  144. private string ConvertToPasswordChar(int length)
  145. {
  146. if (mPasswordBuilder != null)
  147. {
  148. mPasswordBuilder.Clear();
  149. }
  150. else
  151. {
  152. mPasswordBuilder = new StringBuilder();
  153. }
  154. for (var i = 0; i < length; i++)
  155. {
  156. mPasswordBuilder.Append(this.PasswordChar);
  157. }
  158. return mPasswordBuilder.ToString();
  159. }
  160. #endregion
  161. #region Event Implement Function
  162. private void ZPasswordBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
  163. {
  164. if (!this.mIsHandledTextChanged)
  165. return;
  166. foreach (TextChange c in e.Changes)
  167. {
  168. //从密码文中根据本次Change对象的索引和长度删除对应个数的字符
  169. this.Password = this.Password.Remove(c.Offset, c.RemovedLength);
  170. //将Text新增的部分记录给密码文
  171. this.Password = this.Password.Insert(c.Offset, Text.Substring(c.Offset, c.AddedLength));
  172. }
  173. if(!this.ShowPassword)
  174. {
  175. this.SetText(ConvertToPasswordChar(Text.Length));
  176. }
  177. //将光标放到最后面
  178. this.SelectionStart = this.Text.Length + 1;
  179. }
  180. private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
  181. {
  182. }
  183. private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
  184. {
  185. e.Handled = true;
  186. }
  187. #endregion
  188. }
  189. }