【问题标题】:Xamarin.Forms override EditText method is causing an infinite loopXamarin.Forms 覆盖 EditText 方法导致无限循环
【发布时间】:2017-01-03 09:59:34
【问题描述】:

我有两个自定义条目:

  • 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。

【问题讨论】:

  • 您的禁止字符检查会更改文本,然后调用编辑文本。
  • 我认为可能是这样。关于我应该如何重组我的类/方法来做我想做的任何想法?

标签: c# xamarin.forms xamarin.forms.entry


【解决方案1】:

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

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

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

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

【讨论】:

  • 我不确定您在第一行中的意思。我想我需要一个例子来理解。另外,我在方法结束时尝试了 base.EditText,但仍然发生了无限循环。
  • 尝试不覆盖。再次附加到事件中。两个事件处理程序都会触发。
  • 假设我理解正确,仍然会出现无限循环。我删除了 base.EditText 并从 BannedCharactersEntry 中删除了 base() 构造函数。然后我将 TextChanged += EditText 添加到 BannedCharactersEntry 构造函数中。
【解决方案2】:

解决方案非常简单。感谢 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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-27
    • 2021-05-07
    相关资源
    最近更新 更多