Warm tip: This article is reproduced from serverfault.com, please click

c#-无法移至下一个条目并在Xamarin中将重点放在该条目上

(c# - Can't move to Next Entry and Set Focus on it in Xamarin)

发布于 2020-11-27 21:20:44

在我的Xamarin应用程序中,我希望当在Entry中输入值时,它会自动找到下一个Entry字段并为其设置焦点。

我可以使用键盘上的“下一步”按钮移至下一个条目,但是我想在输入值时自动将焦点设置在下一个条目上(最大长度为1个字符)。

我也尝试了这段代码,但是没有用。

.xml

xmlns:behaviors="clr-namespace:Mobile.App.Behaviors"
<Grid Grid.Column="1">
    <Frame CornerRadius="12">
        <BoxView Color="#EEEEEE" />
    </Frame>
    <Entry
        x:Name="PasswordOne"
        Text="{Binding PasswordOne}"
        IsPassword="True"
        Keyboard="Numeric"
        MaxLength="1"
        ReturnType="Next"
        Unfocused="Password_Unfocused">
        <Entry.Behaviors>
            <behaviors:FocusOnReturnBehavior FocusOn="{x:Reference PasswordTwo}" />
        </Entry.Behaviors>
    </Entry>
</Grid>

<Grid Grid.Column="2">
    <Frame CornerRadius="12">
        <BoxView Color="#EEEEEE" />
    </Frame>
    <Entry
        x:Name="PasswordTwo"
        Text="{Binding PasswordTwo}"
        IsPassword="True"
        Keyboard="Numeric"
        MaxLength="1"
        ReturnType="Next"
        Unfocused="Password_Unfocused">
        <Entry.Behaviors>
            <behaviors:FocusOnReturnBehavior FocusOn="{x:Reference PasswordThree}" />
        </Entry.Behaviors>
    </Entry>
</Grid>

FocusOnReturnBehavior.cs

public class FocusOnReturnBehavior : Behavior<Entry>
{
    public VisualElement FocusOn { get; set; }

    protected override void OnAttachedTo(Entry bindable)
    {
        base.OnAttachedTo(bindable);
        bindable.Completed += BindableOnCompleted;
    }


    protected override void OnDetachingFrom(Entry bindable)
    {
        base.OnDetachingFrom(bindable);
        bindable.Completed -= BindableOnCompleted;
    }

    private void BindableOnCompleted(object sender, EventArgs args)
    {
        FocusOn?.Focus();
    }
}
Questioner
user14139029
Viewed
11
Jack Hua 2020-12-01 10:37:20

在你的问题中,completed当你在条目中输入1个字符时不会触发事件。

你可以将条目添加到列表中,并在当前entry.text.length为1时使下一个条目成为焦点

我写了一个简单的例子来实现这一目标:

<StackLayout>
    <!-- Place new controls here -->
    <Entry  MaxLength="1" TextChanged="Entry_TextChanged"
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand" />
    <Entry  MaxLength="1" TextChanged="Entry_TextChanged"
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand" />
    <Entry  MaxLength="1" TextChanged="Entry_TextChanged"
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand" />
    <Entry  MaxLength="1" TextChanged="Entry_TextChanged"
       HorizontalOptions="Center"
       VerticalOptions="CenterAndExpand" />
</StackLayout>

并在后面的代码中:

private void Entry_TextChanged(object sender, TextChangedEventArgs e)
{

    var entry = sender as Entry; // .. and check for null

    if (entry.Text.Length == 1)
    {
        var list = (entry.Parent as StackLayout).Children; //assumes a StackLayout
        var index = list.IndexOf(entry); // 
        var nextIndex = (index + 1) >= list.Count ? 0 : index + 1; //first or next element?
        var next = list.ElementAt(nextIndex);
        next?.Focus();
    }

}

更新:

在后面的代码中:

public partial class MainPage : ContentPage
{

    public List<Entry> myEntryList { get; set; }
    public MainPage()
    {
        InitializeComponent();

        myEntryList = new List<Entry>();
        myEntryList.Add(this.PasswordOne);
        myEntryList.Add(this.PasswordTwo);
    }

    private void Entry_TextChanged(object sender, TextChangedEventArgs e)
    {

        var entry = sender as Entry; // .. and check for null

        if (entry.Text.Length >= 1)
        {                
            var index = myEntryList.IndexOf(entry); // 
            var nextIndex = (index + 1) >= myEntryList.Count ? 0 : index + 1; //first or next element?
            var next = myEntryList.ElementAt(nextIndex);
            next?.Focus();
        }
    }
}

在Xaml中:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="2*" />
        <RowDefinition Height="100" />
        <RowDefinition Height="100" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid Grid.Column="1">
        <Frame CornerRadius="12">
            <BoxView Color="#EEEEEE" />
        </Frame>
        <Entry
            x:Name="PasswordOne"
            Text="PasswordOne"
            IsPassword="True"
            Keyboard="Numeric"
            MaxLength="1"
            ReturnType="Next"
           
            TextChanged="Entry_TextChanged"
            >
        </Entry>
    </Grid>

    <Grid Grid.Column="2">
        <Frame CornerRadius="12">
            <BoxView Color="#EEEEEE" />
        </Frame>
        <Entry
            x:Name="PasswordTwo"
            Text="PasswordTwo"
            IsPassword="True"
            Keyboard="Numeric"
            MaxLength="1"
            ReturnType="Next"
                            
            TextChanged="Entry_TextChanged"

            >   
        </Entry>
    </Grid>

</Grid>