Xamarin表单条目返回类型无法正常工作

时间:2018-08-12 14:46:20

标签: xamarin.forms

我尝试在Xamarin Forms 3中设置新功能ReturnType,并将其设置为Next。我的表单有多个字段,我想确保在按下 Next 按钮时将下一个条目作为焦点。但是,它只是关闭了键盘。我确实阅读了文档,但是找不到将其重点放在下一个Entry上的方法。有人可以指导吗?

谢谢。

2 个答案:

答案 0 :(得分:3)

那些想知道我如何实现它的人,如下:

我创建了一个将处理OnAttachedToOnDetachingFrom的行为,以便可以处理Completed事件来移动焦点。现在,我需要一个BindableProperty。我根据逻辑创建了以下代码:

public class NextEntryBehavior : Behavior<Entry>
{
    public static readonly BindableProperty NextEntryProperty = BindableProperty.Create(nameof(NextEntry), typeof(Entry), typeof(Entry), defaultBindingMode: BindingMode.OneTime, defaultValue: null);

    public Entry NextEntry
    {
        get => (Entry)GetValue(NextEntryProperty);
        set => SetValue(NextEntryProperty, value);
    }

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

    private void Bindable_Completed(object sender, EventArgs e)
    {
        if (NextEntry != null)
        {
            NextEntry.Focus();
        }
    }

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

如您所见,有一个NextEntry属性,一旦用户使用“下一步”按钮将其标记为完成,我们就会通过XAML使用它来关注所需的输入字段。

XAML:

<Entry ReturnType="Next">
    <Entry.Behaviors>
        <behaviors:NextEntryBehavior NextEntry="{x:Reference LastName}" />
    </Entry.Behaviors>
</Entry>

在上述行为中,我使用的LastName引用是当用户单击“下一步”时焦点应移至的控件。 这样,它可以按预期工作,并且可以在整个项目中重复使用。

答案 1 :(得分:0)

ReturnType的属性Entry将仅以图形方式将“键盘中的返回键”设置为指定的类型-在您的情况下为Next

要在视图中为另一个条目设置焦点,您需要在后面的代码中的目标Focus()中调用Entry

例如:

private void txtUsername_OnCompleted(object sender, EventArgs e)
{
    txtPassword.Focus();
}

如果要应用MVVM模式。您需要Entry中的一个属性才能为ViewModel属性绑定。实现此目的的一种方法是扩展Entry控件以添加一个名为“ IsActive”的可绑定属性,并创建一个Trigger来侦听此属性的更改并调用Focus(),如下所示:< / p>

public class ExtendedEntry : Entry
{
    public static readonly BindableProperty IsActiveProperty = BindableProperty.Create(
        nameof(IsActive),
        typeof(bool),
        typeof(ExtendedEntry),
        defaultBindingMode: BindingMode.TwoWay,
        defaultValue: false);

    public bool IsActive
    {
        get => (bool)GetValue(IsActiveProperty);
        set => SetValue(IsActiveProperty, value);
    }

    private Trigger _isActiveTriger;
    private EntryIsActiveAction _activeAction;
    public ExtendedEntry()
    {
        InitTriggers();
    }

    private void InitTriggers()
    {
        InitIsActiveTrigger();
    }

    private void InitIsActiveTrigger()
    {
        _activeAction = new EntryIsActiveAction();
        _isActiveTriger = new Trigger(typeof(ExtendedEntry))
        {
            Value = false,
            Property = IsActiveProperty,
            EnterActions = { _activeAction },
            ExitActions = { _activeAction }
        };

        Triggers.Add(_isActiveTriger);
    }
}


public class EntryIsActiveAction : TriggerAction<ExtendedEntry>
{
    protected override void Invoke(ExtendedEntry sender)
    {
        if (sender.IsActive)
        {
            sender.Focus();
            return;
        }

        sender.Unfocus();
    }
}

示例用法:

Xaml页面:

<Entry x:Name="txtPassword" IsActive="{Binding IsPasswordActive}" />

ViewModel:

    private bool _isPasswordActive;

    public bool IsPasswordActive
    {
        get => _isPasswordActive;
        set
        {
            _isPasswordActive = value;
            OnPropertyChanged();
        }
    }