【发布时间】:2019-03-01 17:18:33
【问题描述】:
我正在尝试在 Xamarin Forms 中创建一个名为 FormElement 的复合视图组件,它由两个标签和一个条目组成:
<?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>
接下来,当用户点击 DONE 按钮时,我想将焦点从 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}" />
【问题讨论】:
-
注意:如果 NextFocus 引用一个简单的 Entry 组件,上面的代码可以正常工作。我只是不知道如何捕捉 FormEntry 组件的 Focused 事件。
-
你能在这里提供完整的演示吗?因为我对你的问题不是特别清楚。
-
在我已经包含的示例 sn-p 中,登录屏幕,我的问题是:如何让用户从“usernameEntry”FormEntry 组件切换到“passwordEntry”FormEntry 组件按下键盘完成按钮?如果“passwordEntry”只是一个条目,而不是我的 FormEntry 组件,那么一切正常:焦点从“usernameEntry”切换到“passwordEntry”;我无法让 FormEntry 获得焦点。
标签: forms xamarin layout focus