Xamarin.Forms 覆盖 EditText 方法导致无限循环
Xamarin.Forms override EditText method is causing an infinite loop
我有两个自定义条目:
MaxLengthEntry : Entry
BannedCharactersEntry : MaxLengthEntry
问题是当用户输入一个允许的字符并且超过条目的最大长度时,会出现无限循环。
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
被调用。从来没有。
我有两个自定义条目:
MaxLengthEntry : Entry
BannedCharactersEntry : MaxLengthEntry
问题是当用户输入一个允许的字符并且超过条目的最大长度时,会出现无限循环。
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
被调用。从来没有。