Xamarin布局无法获得焦点

时间:2019-03-01 17:18:33

标签: forms xamarin layout focus

我正在尝试在Xamarin表单中创建一个名为FormElement的复合视图组件,该组件由两个标签和一个Entry组成:

<?xml version="1.0" encoding="UTF-8"?>
<StackLayout xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:custom="clr-namespace:Mynamespace;assembly=Mynamespace"
         x:Class="Mynamespace.Components.FormEntry">
    <StackLayout Orientation="Horizontal">
        <Label x:Name="formRequiredStar"
               IsVisible="{Binding IsRequired}"
               Text="*" TextColor="Red"
               FontSize="15"
               FontAttributes="Bold"
               Margin="-12,0,0,0"
               HorizontalOptions="Start" />
        <Label x:Name="formLabel"
               HorizontalOptions="Start"
               Text="{Binding LabelText}"
               TextColor="{Binding LabelTextColor}"
               FontSize="{Binding LabelTextFontSize}"
               FontAttributes="{Binding LabelTextFontStyle}" />
    </StackLayout>
    <Frame BorderColor="Black"
           CornerRadius="7"
           Padding="5,0"
           Margin="0,-3,0,0"
           HasShadow="false">
        <Entry x:Name="mainEntry"
               Keyboard="{Binding KeybdType}"
               Placeholder="{Binding EntryPlaceHolder}"
               TextColor="Black"
               FontSize="Default"
               HeightRequest="{Binding EntryHeight}" />
    </Frame>
</StackLayout>

接下来,我想在用户点击“完成”按钮时将焦点从Entry切换到“下一个”元素,所以我这样做:

    namespace Mynamespace.Components
    {
        public partial class FormEntry : StackLayout
        {
            public VisualElement NextFocus
            {
                get { return (VisualElement)GetValue(NextFocusProperty); }
                set { SetValue(NextFocusProperty, value); }
            }

            public static readonly BindableProperty NextFocusProperty =
                BindableProperty.Create(nameof(NextFocus),
                                        typeof(VisualElement),
                                        typeof(FormEntry),
                                        null,
                                     Xamarin.Forms.BindingMode.OneWay);

            public FormEntry()
            {
                InitializeComponent();
                BindingContext = this;

                mainEntry.Completed += (s, e) =>
                {
                    if (NextFocus != null)
                    {
                        NextFocus.Focus();
                    }
                };
            }
        }
    }

接下来,为了使FormEntry成为NextFocus的目标,我尝试添加

    this.Focused += (s,e) => { mainEntry.Focus(); };

传递给构造函数,但从未调用该处理函数,并且我还尝试了重写

    public new void Focus() {
        mainEntry.Focus();
    }

但是永远不会调用此方法。布局类是VisualElement的派生类,因此它们应继承Focused。我缺少有关布局对象的东西吗?我可以理解Layout对象通常不是焦点对象,但是事件处理程序应该在那里,所以我应该能够使用它。

下面是在登录屏幕上如何使用FormEntry的示例:

    <!-- Email -->
    <controls:FormEntry x:Name="usernameEntry"
                        Margin="25,40,25,0"
                        IsRequired="true"
                        EntryHeight="40"
                        KeybdType="Email"
                        NextFocus="{x:Reference passwordEntry}"
                        LabelText="{il8n:Translate Emailorusername}"
                        EntryPlaceHolder="{il8n:Translate EnterUsername}">
    </controls:FormEntry>

    <!-- Password -->
    <controls:FormEntry x:Name="passwordEntry"
                        Margin="25,0,25,0"
                        IsRequired="true"
                        EntryHeight="40"
                        LabelText="{il8n:Translate Password}"
                        EntryPlaceHolder="{il8n:Translate EnterPassword}" />

1 个答案:

答案 0 :(得分:0)

我认为您已经获得了nextfocus元素,可以从nextfocus获得mainEntry,如下所示:

 public FormEntry ()
    {
        InitializeComponent ();
        BindingContext = this;

        mainEntry.Completed += (s, e) =>
        {
            if (NextFocus != null)
            {
                FormEntry formentry = (FormEntry)NextFocus;
                Entry entry = formentry.mainEntry;
                entry.Focus();
            }
        };
    }

然后您会发现您将获得焦点。