我正在尝试使文本框仅接受特定字符。
我的TextBox绑定到以下内容:
private string _CompanyID;
public string CompanyID
{
get { return _CompanyID; }
set
{
_CompanyID = UniversalHelpers.sReturnCorrectColumnName(value);
OnPropertyChanged("CompanyID");
}
}
这是被调用的函数:
public static string sReturnCorrectColumnName(string sInput)
{
if(!string.IsNullOrWhiteSpace(sInput))
return Regex.Replace(sInput, @"[^a-zA-Z]", string.Empty).ToUpper();
else
return sInput;
}
(我只允许a-z& A-Z,没有别的。)
最后我的TextBox看起来像这样:
<TextBox Text="{Binding ExcelBindings.CompanyID, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
我不明白的是,即使我的模式设置为TwoWay,用户仍然可以写任何他想要的东西。
我做错了什么?
答案 0 :(得分:4)
您应该使用自定义UI元素,使用“经典”解决方案(如更改侦听器)限制视图侧的输入。
例如,您可以创建一个覆盖TextBox
方法的OnPreviewTextInput
的简单子类型。在那里,您可以决定何时应该进行某些输入,或者何时想要阻止它。
例如,这是一个自定义TextBox,只接受ASCII字母表中的字符:
public class AlphabetTextBox : TextBox
{
private static readonly Regex regex = new Regex("^[a-zA-Z]+$");
protected override void OnPreviewTextInput(TextCompositionEventArgs e)
{
if (!regex.IsMatch(e.Text))
e.Handled = true;
base.OnPreviewTextInput(e);
}
}
当然,您也可以将正则表达式作为文本框的属性,并允许人们从XAML中设置它。这样,您将获得一个可以重复使用的组件,您可以将其用于各种应用程序。
答案 1 :(得分:1)
我使用PreviewtextInput事件执行此操作。我有一个用于多个TextBox的泛型事件,它从配置表中获取正则表达式,但我在这个例子中对正则表达式进行了硬编码。
private void GenericTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
e.Handled = !IsTextAllowed(e.Text, @"[^a-zA-Z]");
}
private static bool IsTextAllowed(string Text, string AllowedRegex)
{
try
{
var regex = new Regex(AllowedRegex);
return !regex.IsMatch(Text);
}
catch
{
return true;
}
}
答案 2 :(得分:0)
问题是,人类按顺序输入数字,傻瓜
要键入&#34; 0.1&#34;,一个合法的字符串,您必须输入&#34; 0。&#34;,这将失败。
另外,从@poke(这很棒)重新接受答案,e.Text值是更改到文本框(击键)。
您必须将此更改添加到当前文本框字符串,然后验证连接的候选字符串,并查看它是否有效。
人类也很狡猾,因此他们会从剪贴板粘贴以解决限制
使用文本框,您将永远无法阻止所有垃圾进入,因为在某些时候用户必须通过垃圾,才能获得有效的字符串。
因此,您可以使用e.Text阻止非法字符输入,或允许顺序步骤失败。但是你仍然需要检查最终的字符串是否有效。
下面是一个文本框的示例,它允许用户输入最多8个十进制位的十进制值,但是他们仍然可以通过从剪贴板粘贴来欺骗它。
////////////////////////
// REGEXTEXTBOX CLASS //
////////////////////////
using System.Windows.Controls; // Textbox
using System.Windows.Input;
using System.Text.RegularExpressions; // Regex
namespace MyNamespace
{
public class RegexTextBox : TextBox
{
private Regex _regex = null;
public Regex Regex
{
get { return _regex; }
set { _regex = value; }
}
///////////////////////////////////////////////////////////////////////
// MEMBERS
protected override void OnPreviewTextInput(TextCompositionEventArgs e)
{
var prefix = "OnPreviewTextInput() - ";
logger.Debug(prefix + "Entering");
string currentText = this.Text;
string candidateText = currentText + e.Text;
// If we have a set regex, and the current text fails,
// mark as handled so the text is not processed.
if (_regex != null && !_regex.IsMatch(candidateText))
{
e.Handled = true;
}
base.OnPreviewTextInput(e);
}
} // end of class RegexTextbox
} // end of MyNamespace
/////////////////////
// MAINWINDOW.XAML //
/////////////////////
//(Window class needs to know your namespace so it needs xmlns:myNamespace="clr-namespace:MyNamespace")
<myNamespace:RegexTextBox
x:Name="textboxPayToAmount"
Text="{Binding PayToAmount}">
</myNamespace:RegexTextBox>
////////////////////////
// MAINWINDOW.XAML.CS //
////////////////////////
namespace MyNamespace
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
textboxPayToAmount.Regex =
new System.Text.RegularExpressions.Regex(@"^\d*(\.\d{0,8})?$");
}
}
}
答案 3 :(得分:-1)
公共共享函数GetWordCount(str作为字符串)为整数 昏暗的集合作为MatchCollection = Regex.Matches(str,“ \ S +”) 退还货款计数 结束功能
公共共享函数GetInWordLimit(字符串作为字符串,max_words作为整数)作为字符串
Dim final As String = ""
Dim count As Integer = Core.StringOperations.GetWordCount(str)
Dim avg_max_length As Integer = max_words * 7
Dim words = str.Split(" ")
If (words.Length > max_words - 1 And count > max_words - 1) Then
Dim index As Integer = 0
For Each word In words
If index >= max_words Then Exit For
final &= word & " "
If Not (Char.IsSeparator(word) Or Char.IsWhiteSpace(word) Or word = "") Then
index += 1
End If
Next
final = final.TrimEnd
Else
final = str
End If
If final.Length > avg_max_length - 1 Then final = final.Substring(0, avg_max_length)
Return final
End Function