Xamarin的.表单覆盖EditText方法导致无限循环



我有两个自定义条目:

  • MaxLengthEntry : Entry
  • BannedCharactersEntry : MaxLengthEntry

问题是当用户输入的字符是允许的并且超过了条目的最大长度时,就会发生无限循环。

在XAML中像这样添加BannedCharactersEntry:

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


MaxLengthEntry 类:

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 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方法被连续调用,或者为什么 forbidden 输出总是12。

你可以绑定你的Text属性到你的viewmodel,并从viewmodel属性中删除字符。

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

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

并且,您不需要将EditText方法设置为公共。它可以是私有的。如果您在两个构造函数中都附加到它。

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

BannedCharactersEntry类中的

EditText方法:

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);
    }

所有我需要做的是从方法返回,如果一个禁止的字符输入,因为MaxLength将永远不会超过,如果禁止的字符在输入时被删除。

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

相关内容

  • 没有找到相关文章

最新更新