0

我有两个自定义条目:

  • MaxLengthEntry : Entry
  • BannedCharactersEntry : MaxLengthEntry

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

BannedCharactersEntry像这样添加到 XAML 中:

<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不断调用该方法或为什么BANNED输出为 12。

4

2 回答 2

0

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

EditTextBannedCharactersEntry类中的方法:

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如果在输入时删除了禁止字符,则永远不会超过。

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

于 2016-08-27T12:44:55.577 回答
0

您可以将您的Text属性绑定到您的视图模型并从 ViewModel 属性中删除该字符。

您也override可以尝试附加TextChangedBannedCharacterEntry.

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

而且,您不必EditText公开您的方法。它可以设为私有。如果您在两个构造函数中都附加到它。

于 2016-08-26T20:08:23.380 回答