回答編集履歴

1 他の解決方法を追記

f-miyu

f-miyu score 1499

2019/05/28 01:26  投稿

問題は、Androidでは、`Appearing`が呼ばれるタイミングが早すぎるところにあります。
なので、`Task.Delay`で少々待ってやるというのが、手っ取り早い解決策です。
```c#
       private async void SetFocus(object sender, EventArgs e)
       {
           await Task.Delay(100);         
           var f = (Binding)FocusControl;
           var s = f.Source as Entry;
           s.Focus();
       }
```  
 
---  
ちょっと本格的に、画面が表示されるタイミングでフォーカスを当てる様なエフェクトを作ってみました。  
 
Androidプロジェクト  
```C#  
[assembly: ResolutionGroupName("BlankApp1")]  
[assembly: ExportEffect(typeof(FocusEffect), nameof(FocusEffect))]  
namespace BlankApp1.Droid  
{  
   public class FocusEffect : PlatformEffect  
   {  
       private Listener _listener;  
 
       protected override void OnAttached()  
       {  
           _listener = new Listener(this);  
           Control.ViewTreeObserver.AddOnPreDrawListener(_listener);  
       }  
 
       protected override void OnDetached()  
       {  
           if (_listener != null)  
           {  
               Control.ViewTreeObserver.RemoveOnPreDrawListener(_listener);  
               _listener = null;  
           }  
       }  
 
       private void Focus()  
       {  
           (Element as VisualElement)?.Focus();  
 
           if (_listener != null)  
           {  
               Control.ViewTreeObserver.RemoveOnPreDrawListener(_listener);  
               _listener = null;  
           }  
       }  
 
       private class Listener : Java.Lang.Object, ViewTreeObserver.IOnPreDrawListener  
       {  
           private FocusEffect _effect;  
 
           public Listener(FocusEffect effect)  
           {  
               _effect = effect;  
           }  
 
           public bool OnPreDraw()  
           {  
               _effect.Focus();  
               return true;  
           }  
       }  
   }  
}  
```  
 
共通プロジェクト  
```C#  
namespace BlankApp1.Effects  
{  
   public class FocusEffect : RoutingEffect  
   {  
       public FocusEffect() : base($"BlankApp1.{nameof(FocusEffect)}")  
       {  
       }  
   }  
}  
```  
 
```xml  
<?xml version="1.0" encoding="utf-8" ?>  
<ContentPage  
   x:Class="BlankApp1.Views.LoginPage"  
   xmlns="http://xamarin.com/schemas/2014/forms"  
   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
   xmlns:b="clr-namespace:BlankApp1.Behavior"  
   xmlns:e="clr-namespace:BlankApp1.Effects"  
   xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"  
   prism:ViewModelLocator.AutowireViewModel="True">  
 
   <StackLayout Style="{StaticResource StackLayoutStyle}">  
       <Entry x:Name="User" >  
           <Entry.Effects>  
               <e:FocusEffect />  
           </Entry.Effects>  
       </Entry>  
   </StackLayout>  
</ContentPage>  
```

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る