C# 使用Backspace按钮将焦点放在Xamarin中的上一个输入字段上
在我的Xamarin应用程序的PIN页面上,有8个输入字段,4个用于PIN,4个用于确认PIN(这里我只粘贴了2个) 当用户在一个字段中输入值时,光标会聚焦在下一个字段上,依此类推。但如果他们错误地输入了值并想清除它,他们就不能通过按Backspace按钮返回到上一个条目。他们必须按那个输入字段才能聚焦 下面是输入字段的代码。如何通过按Backspace按钮返回/聚焦最后一个输入字段 .xmlC# 使用Backspace按钮将焦点放在Xamarin中的上一个输入字段上,c#,.net,xamarin,xamarin.forms,C#,.net,Xamarin,Xamarin.forms,在我的Xamarin应用程序的PIN页面上,有8个输入字段,4个用于PIN,4个用于确认PIN(这里我只粘贴了2个) 当用户在一个字段中输入值时,光标会聚焦在下一个字段上,依此类推。但如果他们错误地输入了值并想清除它,他们就不能通过按Backspace按钮返回到上一个条目。他们必须按那个输入字段才能聚焦 下面是输入字段的代码。如何通过按Backspace按钮返回/聚焦最后一个输入字段 .xml <Entry x:Name="PasswordOne" Te
<Entry
x:Name="PasswordOne"
Text="{Binding PasswordOne}"
IsPassword="True"
Keyboard="Numeric"
MaxLength="1"
ReturnType="Next"
TextChanged="Entry_FieldChanged" />
<local:CustomEntry
x:Name="PasswordOne"
IsPassword="True"
Keyboard="Numeric"
MaxLength="1"
ReturnType="Next"
TextChanged="Entry_FieldChanged"
OnBackspace="CustomEntry_OnBackspace"
Unfocused="Password_Unfocused" />
CustomEntryRenderer
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace Mobile.App.Droid
{
public class CustomEntryRenderer : EntryRenderer, IInputFilter
{
public CustomEntryRenderer(Context context) : base(context)
{
}
public ICharSequence FilterFormatted(ICharSequence source, int start, int end, ISpanned dest, int dstart, int dend)
{
if (string.IsNullOrWhiteSpace(source.ToString()))
{
var entry = (CustomEntry)Element;
entry.OnBackspacePressed();
}
return source;
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control == null)
{
return;
}
if (Control != null)
{
int length = Control.Text.Length;
Control.SetSelection(length);
SetColors();
};
Control.SetFilters(new IInputFilter[] { this });
}
private void SetColors()
{
Control.SetBackgroundColor(Android.Graphics.Color.Transparent);
}
}
}
[程序集:ExportRenderer(typeof(CustomEntry)、typeof(CustomEntryRenderer))]
命名空间Mobile.App.Droid
{
公共类CustomEntryRenderer:EntryRenderer,IIInputFilter
{
公共CustomEntryRenderer(上下文):基本(上下文)
{
}
公共ICharSequence FilterPerformatted(ICharSequence源、int开始、int结束、ISpanned结束、int开始、int结束)
{
if(string.IsNullOrWhiteSpace(source.ToString()))
{
var条目=(CustomEntry)元素;
entry.OnBackspacePressed();
}
返回源;
}
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
if(Control==null)
{
返回;
}
if(控件!=null)
{
int length=Control.Text.length;
控制。设置选择(长度);
设置颜色();
};
Control.SetFilters(新的IIInputFilter[]{this});
}
私有void SetColors()
{
SetBackgroundColor(Android.Graphics.Color.Transparent);
}
}
}
.xml.cs
public PasswordPage()
{
InitializeComponent();
entryList = new List<Entry>();
entryList.Add(PasswordOne);
entryList.Add(PasswordTwo);
entryList.Add(ConfirmPasswordOne);
entryList.Add(ConfirmPasswordTwo);
}
private void Entry_FieldChanged(object sender, TextChangedEventArgs e)
{
var entry = sender as Entry;
const string numregex = "^[0-9]+$";
if (!(!System.Text.RegularExpressions.Regex.IsMatch(entry.Text, numregex) || entry.Text == ""))
{
if (entry.Text.Length >= 1)
{
var index = entryList.IndexOf(entry);
var nextIndex = (index + 1) >= entryList.Count ? 0 : index + 1;
var next = entryList.ElementAt(nextIndex);
if (entry == ConfirmPasswordTwo)
{ }
else
{
next?.Focus();
}
}
}
else
{
var index = entryList.IndexOf(entry);
var prevIndex = (index) == 0 ? 0 : index - 1;
var prev = entryList.ElementAt(prevIndex);
if (entry == PasswordOne)
{ }
else
{
prev?.Focus();
}
}
}
namespace Mobile.App
{
public class CustomEntry : Entry
{
public delegate void BackspaceEventHandler(object sender, EventArgs e);
public event BackspaceEventHandler OnBackspace;
public CustomEntry() { }
public void OnBackspacePressed()
{
OnBackspace?.Invoke(null, null);
}
}
}
public partial class PasswordPage : ContentPage
{
public List<Entry> entryList { get; set; }
public PasswordPage()
{
InitializeComponent();
ValidatePassword();
entryList = new List<Entry>();
entryList.Add(PasswordOne);
entryList.Add(PasswordTwo);
entryList.Add(ConfirmPasswordOne);
entryList.Add(ConfirmPasswordTwo);
}
Entry entry;
private void Entry_FieldChanged(object sender, TextChangedEventArgs e)
{
entry = sender as Entry;
const string numregex = "^[0-9]+$";
if (!(!System.Text.RegularExpressions.Regex.IsMatch(entry.Text, numregex) || entry.Text == ""))
{
if (entry.Text.Length >= 1)
{
var index = entryList.IndexOf(entry);
var nextIndex = (index + 1) >= entryList.Count ? 0 : index + 1;
var next = entryList.ElementAt(nextIndex);
if (entry == ConfirmPasswordTwo)
{ }
else
{
next?.Focus();
}
}
}
//else
//{
// var index = entryList.IndexOf(entry);
// var prevIndex = (index) == 0 ? 0 : index - 1;
// var prev = entryList.ElementAt(prevIndex);
// if (entry == PasswordOne)
// { }
// else
// {
// prev?.Focus();
// }
//}
}
private void CustomEntry_OnBackspace(object sender, EventArgs e)
{
const string numregex = "^[0-9]+$";
if (!(System.Text.RegularExpressions.Regex.IsMatch(entry.Text, numregex) || entry.Text == ""))
{
var last = entryList.ElementAt(entryList.Count - 1);
last?.Focus();
}
else
{
return;
}
}
}
public部分类密码页:ContentPage
{
公共列表条目列表{get;set;}
公共密码页()
{
初始化组件();
验证密码();
entryList=新列表();
entryList.Add(PasswordOne);
entryList.Add(密码2);
entryList.Add(ConfirmPasswordOne);
entryList.Add(confirmPassword2);
}
入境;
私有无效条目\u字段已更改(对象发送方,textchangedventargs e)
{
条目=发送方作为条目;
常量字符串numregex=“^[0-9]+$”;
if(!(!System.Text.RegularExpressions.Regex.IsMatch(entry.Text,numregex)| | entry.Text==“”)
{
如果(entry.Text.Length>=1)
{
var指数=entryList.IndexOf(条目);
var nextIndex=(索引+1)>=entryList.Count?0:索引+1;
var next=entryList.ElementAt(nextIndex);
if(条目==ConfirmPasswordTwo)
{ }
其他的
{
下一步?.Focus();
}
}
}
//否则
//{
//var指数=entryList.IndexOf(条目);
//var prevIndex=(指数)==0?0:指数-1;
//var prev=entryList.ElementAt(prevIndex);
//if(entry==PasswordOne)
// { }
//否则
// {
//prev?.Focus();
// }
//}
}
私有void CustomEntry\u OnBackspace(对象发送方,事件参数e)
{
常量字符串numregex=“^[0-9]+$”;
if(!(System.Text.RegularExpressions.Regex.IsMatch(entry.Text,numregex)| | entry.Text==“”)
{
var last=entryList.ElementAt(entryList.Count-1);
最后一个?.Focus();
}
其他的
{
返回;
}
}
}
.xml
<Entry
x:Name="PasswordOne"
Text="{Binding PasswordOne}"
IsPassword="True"
Keyboard="Numeric"
MaxLength="1"
ReturnType="Next"
TextChanged="Entry_FieldChanged" />
<local:CustomEntry
x:Name="PasswordOne"
IsPassword="True"
Keyboard="Numeric"
MaxLength="1"
ReturnType="Next"
TextChanged="Entry_FieldChanged"
OnBackspace="CustomEntry_OnBackspace"
Unfocused="Password_Unfocused" />
如果要在按下
退格按钮时聚焦到最后一个条目,可以使用自定义渲染器
自定义条目:
public class CustomEntry : Entry
{
public delegate void BackspaceEventHandler(object sender, EventArgs e);
public event BackspaceEventHandler OnBackspace;
public CustomEntry() { }
public void OnBackspacePressed()
{
OnBackspace?.Invoke(null, null);
}
}
自定义渲染器:
[assembly: ExportRenderer(typeof(CustomEntry), typeof(CustomEntryRenderer))]
namespace Test.Droid
{
public class CustomEntryRenderer : EntryRenderer, Android.Text.IInputFilter
{
public CustomEntryRenderer(Context context) : base(context)
{
}
public ICharSequence FilterFormatted(ICharSequence source, int start, int end, ISpanned dest, int dstart, int dend)
{
if (string.IsNullOrWhiteSpace(source.ToString()))
{
var entry = (CustomEntry)Element;
entry.OnBackspacePressed();
}
return source;
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control == null)
{
return;
}
Control.SetFilters(new IInputFilter[] { this });
}
}
}
我的项目中已经有一个自定义渲染器条目(下面是代码)。OnBackspacePressed();表示条目不包含OnBackspacePressed()的定义
是否先创建自定义条目?我在我的CustomEntry控件中定义OnBackspacePressed
在不点击/触摸/点击条目2的情况下,如果您在任何条目上点击退格按钮,您只需返回到上一条条目,再次不点击/点击/点击任何条目
你的退格按钮是什么?在键盘上?当你按下这个按钮时,你想关注最后一个吗?是的,是的,是的谢谢,我遇到了一些问题,我在上面的更新部分发布了它们。我已经更新了我的回复。请检查。我按照你说的更新了代码,没有错误,但是退格无效。。我在上面发布了我的更新代码。。请看一看……哦,对不起。我忘了在CustomEntry\u OnBackspace
中更改代码。请检查一下。现在可以了。这是截图。谢谢,退格有效。。。我想我不清楚,我很抱歉。。我的意思是,如果你输入了错误的PIN,你只需按backspace按钮,你就会返回到上一个(不是上一个条目,而是上一个条目),你可以删除它。。
xmlns:local="clr-namespace:Test"
private void CustomEntry_OnBackspace(object sender, EventArgs e)
{
const string numregex = "^[0-9]+$";
if (!(!System.Text.RegularExpressions.Regex.IsMatch(entry.Text, numregex) || entry.Text == ""))
{
//var last = entryList.ElementAt(entryList.Count - 1);
//last?.Focus();
var index = entryList.IndexOf(entry);
var pre = entryList.ElementAt(index - 1);
pre?.Focus();
}
else
{
return;
}
}