c# - Xamarin 入口控件 TextChanged 事件循环

标签 c# android xamarin xamarin.forms logic

在我的表单上,我有 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/

相关文章:

xamarin - Xamarin 会为其所有应用程序携带其运行时吗?

java - 无法创建ViewModel的实例

java - 在 ListView 中查看页眉和页脚的缓存

c# - 正则表达式 : extract all words out of quotes

c# - WiX 烧录 : how to change 'WixBundleManufacturer' in bootstrapper application?

java - 类 "name"中的构造函数 "Class name"无法应用于房间持久性库中的给定类型

ios - Xamarin UITableView 不会滚动

c# - 通过 MvvmCross View 模型更改 CardView 背景颜色

c# - WPF更新ContainerStyleSelector样式选择

c# - 有没有办法导出visual studio生成的时序图?