我正在使用Xamarin.Forms和Prism创建我的移动应用程序。
我的屏幕上有2个条目。进入屏幕时,我想将焦点放在第一个条目上。 然后,在用户在此条目中输入数据并对其进行验证之后,我要将焦点设置到第二个条目。
基于第一个答案: 我应该做错什么。我创建了一个新的Prism小项目进行测试:
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:testEntry"
x:Class="testEntry.Views.MainPage"
Title="{Binding Title}">
<StackLayout HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
<Label Text="Welcome to Xamarin Forms and Prism!" />
<local:MyEntry Placeholder="" x:Name="entry1" />
<Button Text="set focus on entry1" Clicked="Button_Clicked"/>
</StackLayout>
</ContentPage>
MainPage.xaml.cs
using Xamarin.Forms;
namespace testEntry.Views
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
entry1.Focus(); //Not Working
}
private void Button_Clicked(object sender, EventArgs e)
{
entry1.Focus(); //Working
}
}
}
MyEntry.cs(在主项目中)
using Xamarin.Forms;
namespace testEntry
{
public class MyEntry : Entry
{
}
}
MyEntryRenderer.cs(在Android项目中)
using Android.Content;
using Android.Views;
using Android.Views.Accessibility;
using Xamarin.Forms.Platform.Android;
namespace testEntry.Droid
{
public class MyEntryRenderer : EntryRenderer
{
public MyEntryRenderer(Context context) : base(context)
{
}
public static void Focus(View view)
{
view.SendAccessibilityEvent(EventTypes.ViewFocused);
}
}
}
不幸的是,仍然没有专注于我的领域:'(
答案 0 :(得分:0)
有一种方法可以使用每个平台的辅助功能API。 Xamarin表单尚不具备可访问性的所有平台功能,因此您必须创建一个自定义渲染器,然后在页面的生命周期事件中调用focus方法。
因此,调用此Focus函数将导致应用程序专注于该元素。您通常不希望这样做,因为该应用程序有目的地专注于它所做的事情,因此可访问的用户会获得一致的体验。但是,如果您真的想覆盖默认行为,则在Android中类似
public static void Focus(View view)
{
view.SendAccessibilityEvent(EventTypes.ViewFocused);
}
在iOS中,您必须使用PostNotification API,这将是此版本的
UIAccessibility.PostNotification(UIAccessibilityPostNotification.ScreenChanged, entry element)
您可以深入研究Accessibility Focus以获取确切答案
答案 1 :(得分:0)
最后,感谢Saamer,我找到了另一种使用EventAggregator的方法。
public class FocusChanged : PubSubEvent<String> { }
然后在我的视图模型中:
IEventAggregator _ea;
public MainPageViewModel(INavigationService navigationService, IEventAggregator eventAggregator) : base(navigationService)
{
_ea = eventAggregator;
}
在viewModel中,每当我要将焦点设置为字段时,我都会发送一个事件:
_ea.GetEvent<FocusChanged>().Publish("Source");
在我后面的代码中,我处理了此事件:
IEventAggregator _ea;
public MainPage(IEventAggregator eventAggregator)
{
InitializeComponent();
_ea = eventAggregator;
_ea.GetEvent<FocusChanged>().Subscribe(SetFocusOnControl); //Name of method which will handle this event
}
/// set the focus on entry based on parameter
/// each event value will set focus on a specific entry (example: source is linked to entry txtScanSrc)
private async void SetFocusOnControl(String fieldName)
{
Entry l_view;
switch(fieldName)
{
case "source": l_view = this.FindByName<Entry>("txtScanSrc"); break;
case "quantity": l_view = this.FindByName<Entry>("txtQty"); break;
case "tote": l_view = this.FindByName<Entry>("txtScanTote"); break;
case "pallet": l_view = this.FindByName<Entry>("txtScanPalout"); break;
case "destination": l_view = this.FindByName<Entry>("txtScanDest"); break;
default: l_view = this.FindByName<Entry>("txtScanSrc"); break;
}
await WaitAndExecute(500, () => { l_view.Focus(); });
}