我有两个自定义条目:
-
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
被调用。从来没有。