在iOS中,當您在字段中輸入密碼時,會顯示該字段的最後一個字母,但在鍵入下一個字符時會被混淆。有沒有辦法在WPF中複製這種行爲?WPF中的自定義屏蔽密碼框
回答
好的,如果你在桌面應用程序中使用這樣的東西是合理的,那麼你可以做類似下面的事情。
我們之前有過類似的要求,這就是我所做的。
- 我從
TextBox
派生並添加SecureString
類型,它的一個新的DP創建自定義Passwordbox
。(幾乎相同的概念正常PasswordBox
)。我們不以這種方式放棄任何安全利益,並且可以根據我們心中的內容定製視覺行爲。 - 現在,我們可以使用
TextBox
的Text
,因爲它的顯示字符串並在後端SecureString
DP中保存實際密碼並將其綁定到VM。 - 我們處理
PreviewTextInput
和PreviewKeyDown
事件來管理控件中的所有文本的變化,包括像Key.Back
,Key.Delete
和惱人的Key.Space
東西(不通過PreviewTextInput
iOS的感覺來了:
夫婦有更多的事情要注意一個確切的iOS行爲
- 僅在向「當前字符串的末尾」添加新字符時顯示最後一個字符(
FlowDirection
獨立) - 編輯現有字符串之間的字符對掩碼沒有影響。
- 顯示的最後一個字符與定時器有關(如果空閒,在一段時間後變爲「*」)
- 控件中禁用的所有複製粘貼操作。
首先2分能檢測文本發生變化時很容易進行處理,最後一個我們可以使用一個DispatcherTimer
與顯示字符串相應工作。
所以把所有這一切我們一起結束:
/// <summary>
/// This class contains properties for CustomPasswordBox
/// </summary>
internal class CustomPasswordBox : TextBox {
#region Member Variables
/// <summary>
/// Dependency property to hold watermark for CustomPasswordBox
/// </summary>
public static readonly DependencyProperty PasswordProperty =
DependencyProperty.Register(
"Password", typeof(SecureString), typeof(CustomPasswordBox), new UIPropertyMetadata(new SecureString()));
/// <summary>
/// Private member holding mask visibile timer
/// </summary>
private readonly DispatcherTimer _maskTimer;
#endregion
#region Constructors
/// <summary>
/// Initialises a new instance of the LifeStuffPasswordBox class.
/// </summary>
public CustomPasswordBox() {
PreviewTextInput += OnPreviewTextInput;
PreviewKeyDown += OnPreviewKeyDown;
CommandManager.AddPreviewExecutedHandler(this, PreviewExecutedHandler);
_maskTimer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 0, 1) };
_maskTimer.Tick += (sender, args) => MaskAllDisplayText();
}
#endregion
#region Commands & Properties
/// <summary>
/// Gets or sets dependency Property implementation for Password
/// </summary>
public SecureString Password {
get {
return (SecureString)GetValue(PasswordProperty);
}
set {
SetValue(PasswordProperty, value);
}
}
#endregion
#region Methods
/// <summary>
/// Method to handle PreviewExecutedHandler events
/// </summary>
/// <param name="sender">Sender object</param>
/// <param name="executedRoutedEventArgs">Event Text Arguments</param>
private static void PreviewExecutedHandler(object sender, ExecutedRoutedEventArgs executedRoutedEventArgs) {
if (executedRoutedEventArgs.Command == ApplicationCommands.Copy ||
executedRoutedEventArgs.Command == ApplicationCommands.Cut ||
executedRoutedEventArgs.Command == ApplicationCommands.Paste) {
executedRoutedEventArgs.Handled = true;
}
}
/// <summary>
/// Method to handle PreviewTextInput events
/// </summary>
/// <param name="sender">Sender object</param>
/// <param name="textCompositionEventArgs">Event Text Arguments</param>
private void OnPreviewTextInput(object sender, TextCompositionEventArgs textCompositionEventArgs) {
AddToSecureString(textCompositionEventArgs.Text);
textCompositionEventArgs.Handled = true;
}
/// <summary>
/// Method to handle PreviewKeyDown events
/// </summary>
/// <param name="sender">Sender object</param>
/// <param name="keyEventArgs">Event Text Arguments</param>
private void OnPreviewKeyDown(object sender, KeyEventArgs keyEventArgs) {
Key pressedKey = keyEventArgs.Key == Key.System ? keyEventArgs.SystemKey : keyEventArgs.Key;
switch (pressedKey) {
case Key.Space:
AddToSecureString(" ");
keyEventArgs.Handled = true;
break;
case Key.Back:
case Key.Delete:
if (SelectionLength > 0) {
RemoveFromSecureString(SelectionStart, SelectionLength);
} else if (pressedKey == Key.Delete && CaretIndex < Text.Length) {
RemoveFromSecureString(CaretIndex, 1);
} else if (pressedKey == Key.Back && CaretIndex > 0) {
int caretIndex = CaretIndex;
if (CaretIndex > 0 && CaretIndex < Text.Length)
caretIndex = caretIndex - 1;
RemoveFromSecureString(CaretIndex - 1, 1);
CaretIndex = caretIndex;
}
keyEventArgs.Handled = true;
break;
}
}
/// <summary>
/// Method to add new text into SecureString and process visual output
/// </summary>
/// <param name="text">Text to be added</param>
private void AddToSecureString(string text) {
if (SelectionLength > 0) {
RemoveFromSecureString(SelectionStart, SelectionLength);
}
foreach (char c in text) {
int caretIndex = CaretIndex;
Password.InsertAt(caretIndex, c);
MaskAllDisplayText();
if (caretIndex == Text.Length) {
_maskTimer.Stop();
_maskTimer.Start();
Text = Text.Insert(caretIndex++, c.ToString());
} else {
Text = Text.Insert(caretIndex++, "*");
}
CaretIndex = caretIndex;
}
}
/// <summary>
/// Method to remove text from SecureString and process visual output
/// </summary>
/// <param name="startIndex">Start Position for Remove</param>
/// <param name="trimLength">Length of Text to be removed</param>
private void RemoveFromSecureString(int startIndex, int trimLength) {
int caretIndex = CaretIndex;
for (int i = 0; i < trimLength; ++i) {
Password.RemoveAt(startIndex);
}
Text = Text.Remove(startIndex, trimLength);
CaretIndex = caretIndex;
}
private void MaskAllDisplayText() {
_maskTimer.Stop();
int caretIndex = CaretIndex;
Text = new string('*', Text.Length);
CaretIndex = caretIndex;
}
#endregion
}
工作示例:
您可以輸入一些東西到控制和檢查顯示的儲值在它下面。
在本示例中,我添加了一個新的DP類型string
,以表明控件正常工作。你會不想在你的實時代碼中使用DP(HiddenText
),但我希望這個示例有助於分析這個類是否真正起作用:)
哇,謝謝Viv!這正是我尋找的東西的類型!感謝您幫助WPF新手。 – aceinthehole
出於某種原因,我不能綁定''Password''-DP。它根本不會更新。 SecureString是不是可綁定的?我在我的應用程序的每個地方都使用SecureString,直到我必須將其存儲到文件中。然後我得到臨時字符串,並立即使用定義的密鑰對其進行加密。同樣的,當我讀到價值。所以SecureString對我認爲的這種設計非常有用。但我無法使用Bindings = / – ecth
- 1. .NET MVC屏蔽密碼文本框
- 2. 屏蔽文本框中的自定義日期格式
- 3. 如何屏蔽日誌中的密碼?
- 4. Android自定義鎖定屏幕密碼
- 5. 在cygwin中未屏蔽perforce密碼
- 6. 取消屏蔽密碼文本框中不能正常工作
- 7. WPF MVVM密碼框綁定
- 8. 安裝屏蔽中的自定義操作中的問題2010
- 9. Java 1.5命令行密碼屏蔽
- 10. 禁用屏蔽輸入類型密碼
- 11. 屏蔽文本框 - 隱藏屏蔽
- 12. 我怎麼能揭露C#密碼文本框和屏蔽回密碼
- 13. 如何屏蔽自定義控件中的值
- 14. 自定義密碼的Winform
- 15. 屏蔽WPF中的滾動文本
- 16. WPF自定義文本框
- 17. WPF自定義文本框
- 18. WPF:自定義消息框
- 19. 自定義消息框WPF
- 20. C#WPF中的自定義列表框?
- 21. WPF中的自定義列表框
- 22. WPF中的自定義形狀邊框
- 23. 設定屏蔽%的
- 24. WPF中XmlDataProvider的自定義源代碼
- 25. 自定義WPF DatePicker掩碼
- 26. 的WebSphere自定義密碼加密
- 27. 「鎖定屏幕」與自定義安全密碼
- 28. 從HTML Webforms中的用戶屏蔽密碼
- 29. 密碼輸入自定義
- 30. 密碼框IsPasswordRevealButtonEnabled顯示自定義樣式的複選框
如果你這樣做,這被認爲是不好的做法在桌面應用上。考慮一下這樣一個事實,在手機上,人們看着你的肩膀遠遠不及桌面上的大型顯示器。所以除非你打算在Windows手機或平板電腦上使用。再想一想。 – Viv
@Viv是有道理的,但不幸的是,我不是在這種情況下規定要求。 – aceinthehole
@Viv plus,這個應用程序可能會被那些傾向於視覺受損的人使用,在這種情況下可能會更有意義。 – aceinthehole