简体   繁体   English

在 Xamarin.Forms 中完成行为更改条目的焦点

[英]Change focus on entry completed with behavior in Xamarin.Forms

I want to change focus from one entry to other entry.我想将焦点从一个条目更改为另一个条目。

At first, I changed with Focus() method for all entry.起初,我为所有条目更改了 Focus() 方法。 But I think it's not good code, because the more entry, the more difficult to edit.但我认为这不是好的代码,因为条目越多,编辑就越困难。

So I found reference from here https://adenearnshaw.com/focus-next-element-on-enter/所以我从这里找到了参考https://adenearnshaw.com/focus-next-element-on-enter/

First, create behavior一、创造行为

public class SetFocusOnEntryCompletedBehavior : Behavior
{
    public static readonly BindableProperty TargetElementProperty
       = BindableProperty.Create(nameof(TargetElement), typeof(VisualElement), typeof(SetFocusOnEntryCompletedBehavior));

    public VisualElement TargetElement
    {
        get => (VisualElement)GetValue(TargetElementProperty);
        set => SetValue(TargetElementProperty, value);
    }
        
    protected override void OnAttachedTo(BindableObject bindable)
    {
        base.OnAttachedTo(bindable);
        
        if (bindable is Entry entry)
            entry.Completed += Entry_Completed;
    }

    protected override void OnDetachingFrom(BindableObject bindable)
    {
        if (bindable is Entry entry)
            entry.Completed -= Entry_Completed;

        base.OnDetachingFrom(bindable);
    }

    private void Entry_Completed(object sender, EventArgs e)
    {
        TargetElement?.Focus();
    }
}

Next, implement in xaml接下来在xaml中执行

<ContentPage x:Class="NextFormFieldSample.Forms.MainPage"
             xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:behaviors="clr-namespace:NextFormFieldSample.Forms.Behaviors">
    <StackLayout Margin="20">   
        
        <Entry Placeholder="Field 1">
            <Entry.Behaviors>
                <behaviors:SetFocusOnEntryCompletedBehavior TargetElement="{x:Reference Entry2}" />
            </Entry.Behaviors>
        </Entry>

        <Entry x:Name="Entry2" Placeholder="Field 2"/>  
        
    </StackLayout>
</ContentPage>

But.!!!但。!!! I have to add one more thing for using this.我必须再添加一件事才能使用它。

I have to receive result after entry completed event;我必须在输入完成事件后收到结果; If the result is true, focus changed.如果结果为真,焦点就改变了。 If not, focus stayed again.如果没有,焦点再次停留。

I tried to make behaviors.我试着做出行为。 But it's very difficult for me.但这对我来说非常困难。

Are there anybody help me?有人帮帮我吗?

That is, with some result from database, if the result is true, focus is changed.也就是说,对于来自数据库的某些结果,如果结果为真,则更改焦点。 But if that is false, focus stay on same entry.但如果那是错误的,焦点就会停留在同一个条目上。 Not only just change the focus of entry, but watch the result from database.不仅改变了输入的焦点,还观察了数据库的结果。

Then you can add some logical judgment to the event Entry_Completed .然后就可以给Entry_Completed这个事件加上一些逻辑判断了。

Please refer to the following code:请参考以下代码:

<ContentPage.Content> 
    <StackLayout Margin="20">
  
        <Entry x:Name="Entry1"
           Placeholder="Field 1"
           Completed="Entry_Completed"
           TabIndex="1">

        </Entry>
   
        <Entry x:Name="Entry2"
           Placeholder="Field 2"
           Completed="Entry_Completed"
           TabIndex="2">

        </Entry>        

        <Entry x:Name="Entry3"
           Placeholder="Field 3"
           Completed="Entry_Completed"
           TabIndex="3">
        </Entry>

        <Entry x:Name="Entry4"
           Placeholder="Field 4"
           Completed="Entry_Completed"
           TabIndex="4" />
    </StackLayout>
</ContentPage.Content>

Event Entry_Completed in YourPage.xaml.cs Entry_Completed中的事件 Entry_Completed

   private void Entry_Completed(object sender, EventArgs e) 
    {
        var entry = sender as Entry; // .. and check for null

        // get result from database here

        if (entry.Text.Length == 2) // here I used string's length(2) as the logical condition
        {
            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();
        }
      }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM