Xamarin Layout 无法获得焦点
Xamarin Layout can't receive focus
我正在尝试在 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>
接下来,我想在用户点击“完成”按钮时将焦点从 Entry 切换到 "next" 元素,所以我这样做:
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 对象的某些信息吗?我可以理解 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 元素,你可以从 nextfocus 得到 mainEntry,像这样:
public FormEntry ()
{
InitializeComponent ();
BindingContext = this;
mainEntry.Completed += (s, e) =>
{
if (NextFocus != null)
{
FormEntry formentry = (FormEntry)NextFocus;
Entry entry = formentry.mainEntry;
entry.Focus();
}
};
}
然后你会发现你会得到焦点。
我正在尝试在 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>
接下来,我想在用户点击“完成”按钮时将焦点从 Entry 切换到 "next" 元素,所以我这样做:
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 对象的某些信息吗?我可以理解 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 元素,你可以从 nextfocus 得到 mainEntry,像这样:
public FormEntry ()
{
InitializeComponent ();
BindingContext = this;
mainEntry.Completed += (s, e) =>
{
if (NextFocus != null)
{
FormEntry formentry = (FormEntry)NextFocus;
Entry entry = formentry.mainEntry;
entry.Focus();
}
};
}
然后你会发现你会得到焦点。