在我的表单上,我有 3 个 entry
控件。我正在尝试使用以下验证规则验证“年龄”控件:
不能输入超过 3 位数字
不能输入小数位(.)
不能输入连字符 (-)
为此,我将控件的“TextChanged”属性设置为
TextChanged="OnAgeTextChanged"
我的 OnAgeTextChanged
方法是:
private void OnAgeTextChanged(object sender, TextChangedEventArgs e)
{
var entry = (Entry)sender;
try
{
if (entry.Text.Length > 3)
{
string entryText = entry.Text;
entry.TextChanged -= OnAgeTextChanged;
entry.Text = e.OldTextValue;
entry.TextChanged += OnAgeTextChanged;
}
string strName = entry.Text;
if (strName.Contains(".") || strName.Contains("-"))
{
strName = strName.Replace(".", "").Replace("-", "");
entry.Text = strName;
}
}
catch(Exception ex)
{
Console.WriteLine("Exception caught: {0}", ex);
}
}
但是,当满足if条件时,事件会被多次循环,导致应用运行缓慢。
例如,如果我输入我的年龄 1234,它会多次循环代码,因此会出现延迟,每次更改文本时延迟都会增加。
还有什么其他方法可以实现此验证,但不会多次调用该事件?
编辑
在更新代码以删除控件上的 TextChanged
触发器之后,在方法结束时重新分配它之前,它仍然循环多次,并且循环次数随着每个键的增加而增加按。
入口控制xaml
<Entry x:Name="txtAge"
Placeholder="Age"
Keyboard="Numeric"
TextColor="DarkBlue"
PlaceholderColor="DarkBlue"
Completed="AgeCompleted"
HorizontalOptions="Start"
WidthRequest="55"
TextChanged="OnAgeTextChanged"
/>
TextChanged
事件
private void OnAgeTextChanged(object sender, TextChangedEventArgs e)
{
var entry = (Entry)sender;
try
{
entry.TextChanged -= OnAgeTextChanged;
if (entry.Text.Length > 3)
{
entry.Text = e.OldTextValue;
}
string strName = entry.Text;
if (strName.Contains(".") || strName.Contains("-"))
{
strName = strName.Replace(".", "").Replace("-", "");
entry.Text = strName;
}
}
catch(Exception ex)
{
Console.WriteLine("Exception caught: {0}", ex);
}
finally
{
entry.TextChanged += OnAgeTextChanged;
}
}
最佳答案
我最终解决这个问题的方法是使用一个单独的类来处理我的验证。
我的验证类:
using System.ComponentModel;
using System.Runtime.CompilerServices;
public class viewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string age_;
public string Age { get { return age_; } set { if (age_ != value) { age_ = ProcessAge(value); OnPropertyChanged(); } } }
private string ProcessAge(string age)
{
if (string.IsNullOrEmpty(age))
return age;
if (age.Length > 3)
age = age.Substring(0, 3);
if (age.StartsWith("0"))
age = age.Remove(0, 1);
return age.Replace(".", "").Replace("-", "");
}
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
然后,我可以绑定(bind)表单以使用此类,方法是:
public MainPage()
{
InitializeComponent();
BindingContext = new viewModel();
}
最后,为了绑定(bind)入口控件以使用 Age 属性,我设置了 Text
属性
Text="{Binding Age, Mode=TwoWay}"
这现在所做的是,每次 Age 控件中的值发生变化时,它都会查看新类中的 Age 属性并查看要设置它,它需要通过 ProcessAge
验证它,这就是现在完成检查的地方。
这样速度更快,因为每次按键只发生一次,而且订阅和取消订阅 TextChanged
事件不需要摆弄,也没有循环。
关于c# - Xamarin 入口控件 TextChanged 事件循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50878023/