Xamarin.Forms 覆盖 EditText 方法导致无限循环

Xamarin.Forms override EditText method is causing an infinite loop

我有两个自定义条目:

问题是当用户输入一个允许的字符并且超过条目的最大长度时,会出现无限循环。

BannedCharactersEntry 像这样添加到 XAML 中:

<local:BannedCharactersEntry BannedCharacters="369" Text="1" Keyboard="Numeric" MaxLength="1" />


MaxLengthEntry class:

class MaxLengthEntry : Entry
{
    public MaxLengthEntry()
    {
        base.TextChanged += EditText;
    }

    public virtual void EditText(object sender, TextChangedEventArgs args)
    {
        Entry e = sender as Entry;
        String val = e.Text;

        if (string.IsNullOrEmpty(val))
            return;

        if (Uppercase)
            val = val.ToUpper();

        if (MaxLength > 0 && val.Length > MaxLength)
        {
            val = val.Remove(val.Length - 1);
        }
        e.Text = val;
        Debug.WriteLine("MAX: " + val);
    }

    public static readonly BindableProperty UppercaseProperty = BindableProperty.Create<MaxLengthEntry, bool>(p => p.Uppercase, false);

    public bool Uppercase
    {
        get
        {
            return (bool)GetValue(UppercaseProperty);
        }
        set
        {
            SetValue(UppercaseProperty, value);
        }
    }

    public static readonly BindableProperty MaxLengthProperty = BindableProperty.Create<MaxLengthEntry, int>(p => p.MaxLength, 0);

    public int MaxLength
    {
        get
        {
            return (int)GetValue(MaxLengthProperty);
        }
        set
        {
            SetValue(MaxLengthProperty, value);
        }
    }
}

BannedCharactersEntry class:

class BannedCharactersEntry : MaxLengthEntry
{
    public static readonly BindableProperty BannedCharactersProperty =
  BindableProperty.Create("BannedCharacters", typeof(string), typeof(BannedCharactersEntry), null);

    public string BannedCharacters
    {
        get { return (string)GetValue(BannedCharactersProperty); }
        set { SetValue(BannedCharactersProperty, value); }
    }

    public BannedCharactersEntry() : base()
    {

    }

    public override void EditText(object sender, TextChangedEventArgs args)
    {
        base.EditText(sender, args);

        Entry e = sender as Entry;
        String val = e.Text;

        Debug.WriteLine("BANNED: " + val);

        if (string.IsNullOrEmpty(val))
            return;

        foreach (char c in BannedCharacters)
        {
            if (val[val.Length - 1] == c)
            {
                val = val.Remove(val.Length - 1);
                break;
            }
        }

        e.Text = val;
    }
}

BannedCharactersEntry 的初始值为 1。然后我按 2。
输出如下:

最大:1 禁止:12
最大:1 禁止:1
最大:1 禁止:12
最大:1 禁止:1
等...

我不知道为什么 EditText 方法被连续调用或者为什么 BANNED 输出总是 12。

您只需将 Text 属性 绑定到您的视图模型,然后从视图模型 属性 中删除角色。

此外,您可以尝试在 BannedCharacterEntry 中附加到 TextChanged 的事件,而不是 override

此外,您还在覆盖函数的开头调用了 base.EditText,这将更改文本,但在继续执行时,您使用的是原始值而不是更改后的值。您可以在重写函数的末尾调用 base.EditText

而且,您不需要像 public 那样使用 EditText 方法。它可以设为私有。如果您在两个构造函数中都附加到它。

解决方法非常简单。感谢 Rohit 为我指明了正确的方向!

EditText BannedCharactersEntry 中的方法 class:

protected override void EditText(object sender, TextChangedEventArgs args)
    {
        Entry e = sender as Entry;
        String val = e.Text;

        if (string.IsNullOrEmpty(val))
            return;

        foreach (char c in BannedCharacters)
        {
            if (val[val.Length - 1] == c)
            {
                val = val.Remove(val.Length - 1);
                e.Text = val;
                return;
            }
        }

        base.EditText(sender, args);
    }

如果输入了禁止字符,我需要做的就是从方法中 return,因为如果在输入时删除禁止字符,则永远不会超过 MaxLength

否则,MaxLengthEntry.EditText 将通过 base.EditText 调用。我不需要担心无限循环,因为文本已更改或 base.EditText 被调用。从来没有。