我正在尝试弄清楚如何在发生验证错误时取消TextBox
中的用户输入。如果用户尝试输入无效字符,我希望阻止将其添加到TextBox
。
如何添加或修改以下代码以防止TextBox
接受无效字符?是否可以不收听TextBox.TextChanged
事件?
我的TextBox
看起来像是:
<TextBox Validation.Error="OnSomeTextBoxValidationError">
<TextBox.Text>
<Binding Path="Value" NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:SomeValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
我的自定义验证规则如下:
public class SomeValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
string hex_string = value as string;
Match invalid_chars = Regex.Match(hex_string, "[^0-9a-fA-F]");
bool is_valid = (invalid_chars.Success == false);
string error_context = null;
if (is_valid == false)
{
error_context = "Invalid characters";
}
return new ValidationResult(is_valid, error_context);
}
}
我有一个错误处理程序...我能用它做什么吗?
private void OnSomeTextBoxValidationError(object sender, ValidationErrorEventArgs e)
{
// Can I do anything here?
}
如果可能,请提供原始答案,而不是引用网址。我已经阅读了许多涉及事件处理程序的可能解决方案,但我没有遇到任何人讨论在ValidationRule
中进行所有验证的可能性。
答案 0 :(得分:6)
经过大量研究后,似乎完全控制TextBox
输入的唯一方法是直接处理多个事件。根据C#2008中的WPF食谱(第1版,第169页):
不幸的是,没有简单的方法(目前)将有用的高级数据绑定功能与低级键盘处理相结合,这是防止用户完全键入无效字符所必需的。
以下是我创建的十六进制数字TextBox
,它只接受字符a-f,A-F和0-9。
<TextBox
x:Name="SomeTextBox"
LostFocus="TextBoxLostFocus"
PreviewKeyDown="TextBoxPreviewKeyDown"
PreviewTextInput="TextBoxPreviewTextInput" />
private string mInvalidCharPattern = "[^0-9a-fA-F]";
// In my case SomeClass derives from UserControl
public SomeClass()
{
DataObject.AddPastingHandler(
this.SomeTextBox,
new DataObjectPastingEventHandler(TextBoxPasting));
}
private void TextBoxLostFocus(object sender, RoutedEventArgs e)
{
// You may want to refresh the TextBox's Text here. If the user deletes
// the contents of the TextBox and clicks off of it, then you can restore
// the original value.
}
// Catch the space character, since it doesn't trigger PreviewTextInput
private void TextBoxPreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Space) { e.Handled = true; }
}
// Do most validation here
private void TextBoxPreviewTextInput(object sender, TextCompositionEventArgs e)
{
if (ValidateTextInput(e.Text) == false) { e.Handled = true; }
}
// Prevent pasting invalid characters
private void TextBoxPasting(object sender, DataObjectPastingEventArgs e)
{
string lPastingText = e.DataObject.GetData(DataFormats.Text) as string;
if (ValidateTextInput(lPastingText) == false) { e.CancelCommand(); }
}
// Do the validation in a separate function which can be reused
private bool ValidateTextInput(string aTextInput)
{
if (aTextInput == null) { return false; }
Match lInvalidMatch = Regex.Match(aTextInput, this.mInvalidCharPattern);
return (lInvalidMatch.Success == false);
}
答案 1 :(得分:1)
你可能已经看过这个,但这是最简单的解决方案,并且一直对我有用。我捕获了PreviewKeyDown事件和..
<TextBox PreviewKeyDown="TextBox_PreviewKeyDown" Width="150" Height="30"></TextBox>
private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
... validation here, eg. to stop spacebar from being pressed, you'd use:
if (e.Key == Key.Space) e.Handled = true;
}
答案 2 :(得分:0)
我在Windows Phone Runtime 8.1应用程序中使用它只允许某些字符:
<TextBox x:Name="TextBoxTitle"
MaxLength="24"
InputScope="AlphanumericHalfWidth"
TextChanged="TextBoxTitle_TextChanged"
KeyUp="TextBoxTitle_KeyUp"
Paste="TextBoxTitle_Paste"/>
using System.Text.RegularExpressions;
bool textBoxTitle_TextPasted = false;
private void TextBoxTitle_Paste(object sender, TextControlPasteEventArgs e)
{
textBoxTitle_TextPasted = true;
}
// only allow characters A-Z, a-z, numbers and spaces
private void TextBoxTitle_TextChanged(object sender, TextChangedEventArgs e)
{
string fileNameCompatibleString = Regex.Replace(TextBoxTitle.Text, "[^a-zA-Z0-9\x20]", String.Empty);
if (TextBoxTitle.Text != fileNameCompatibleString)
{
if (textBoxTitle_TextPasted)
{
TextBoxTitle.Text = fileNameCompatibleString;
TextBoxTitle.SelectionStart = fileNameCompatibleString.Length;
}
else
{
int selectionStartSaved = TextBoxTitle.SelectionStart;
TextBoxTitle.Text = fileNameCompatibleString;
TextBoxTitle.SelectionStart = selectionStartSaved-1;
}
}
textBoxTitle_TextPasted = false;
}
// close SIP keyboard on enter key up
private void TextBoxTitle_KeyUp(object sender, KeyRoutedEventArgs e)
{
if (e.Key == Windows.System.VirtualKey.Enter)
{
Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().CoreWindow.IsInputEnabled = false;
Windows.ApplicationModel.Core.CoreApplication.GetCurrentView().CoreWindow.IsInputEnabled = true;
e.Handled = true;
}
}
答案 3 :(得分:0)
在TextBox PreviewKeyUp事件运行良好之后。通过将发件人转换为TextBox,在文本框中捕获当前文本。然后使用RegEx替换来替换无效字符。也可以在此处添加一些工具提示文本,但是现在这会删除无效字符并将背景变为红色,以立即获得用户反馈。