代码之家  ›  专栏  ›  技术社区  ›  nicks

为什么entry的Focus()方法在页面的构造函数中不起作用?

  •  2
  • nicks  · 技术社区  · 8 年前

    public SomePage()
    {
        InitializeComponent();
        someEntry.Focus();
    }
    

    但是,如果我使用以下代码,则默认情况下代码条目不会聚焦:

    protected override void OnAppearing()
    {
        base.OnAppearing();
        someEntry.Focus();
    }
    

    它可以根据需要工作(条目是有重点的)。这是为什么?codeEntry是否已经存在并位于其位置,功能齐全 InitializeComponent() 呼叫我是说,我当然可以改变 Text 页构造函数中的属性。

    6 回复  |  直到 8 年前
        1
  •  3
  •   Akash Kava    8 年前

    在Xamarin中,每个控件都有等效的视图渲染器,即原生UI元素,只有在将控件添加到原生元素层次结构时才会创建该元素。在构造函数中,尚未创建条目的本机元素。然而,在OnAppering中,条目的相应本机元素被创建,以便它能够获得焦点。

    此外,这似乎是一个错误,因为Xamarin正在存储状态并在创建原生UI元素时应用它。是时候提交一个bug了!!!

        2
  •  3
  •   Wim Kuijpers    3 年前

    当我使用Shell时,这不再有效。

    protected override void OnAppearing()
    {
        base.OnAppearing();
        someEntry.Focus();
    }
    

    但这确实有效:

    protected async override void OnAppearing()
    {
         base.OnAppearing();
    
         await Task.Delay(100);
    
         someEntry.Focus();
    }
    
        3
  •  1
  •   Yasin Patel    4 年前

    文件.xaml

    <Entry x:Name="txtLPN" Placeholder="Scan LPN." Grid.Row="1" Grid.Column="0" FontSize="15" Focused="txtLPN_Focused" />
    

    文件cs>>>>>

    private void txtLPN_Focused(object sender, FocusEventArgs e)
    {
        txtLPN.CursorPosition = 0;
        if (!string.IsNullOrEmpty(txtLPN.Text))
           txtLPN.SelectionLength = txtLPN.Text.Length;
    }
    protected async override void OnAppearing()
    {
        base.OnAppearing();
        await Task.Delay(600);
        txtLPN.Focus();
    }
    
        4
  •  1
  •   Sean McAvoy    4 年前

    我尝试了以上所有方法。我认为,因为我的页面是一个弹出式窗口,并且有一些动画,所以上述内容都不起作用。然而,这对我来说很管用:

    BackgroundWorker setFocus = new BackgroundWorker();
    

    在构造函数中

    setFocus.DoWork += SetFocus_DoWork;
    
    private void SetFocus_DoWork(object sender, DoWorkEventArgs e)
    {
           bool worked = false;
           while (!worked)//will keep trying until it can set focus (when MyEntry is rendered)
           {
               Thread.Sleep(1);
               MainThread.InvokeOnMainThreadAsync(()=> worked = MyEntry.Focus());
           }
    }
    protected override void OnAppearing()
    {
         base.OnAppearing();
         if(!setFocus.IsBusy)
         {
             setFocus.RunWorkerAsync();
         }
    }
    

    如果从未将“worked”设置为true,您可能需要添加一些要处理的内容,比如尝试几秒钟。

        5
  •  1
  •   Trevor Balcom    2 年前

    您可以使用Xamarin社区工具包 LifecycleEffect 在初始化/清理Entry的渲染器时调用一些代码。将此与 OnAppearing 不用便宜就能可靠地显示键盘 DoEvents 黑客之类的 await Task.Yield() await Task.Delay(100) .

    XAML:

    <Entry x:Name="userName">
        <Entry.Effects>
            <xct:LifecycleEffect Loaded="LifecycleEffect_Loaded" Unloaded="LifecycleEffect_Unloaded" />
        </Entry.Effects>
    </Entry>
    

    C#编号:

    private bool userNameLoaded = false;
    
    protected override void OnAppearing()
    {
        base.OnAppearing();
        if (userNameLoaded)
        {
            userName.Focus();
        }
    }
    
    private void LifecycleEffect_Loaded(object sender, System.EventArgs e)
    {
        if (sender == userName)
        {
            userNameLoaded = true;
            userName.Focus();
        }
    }
    
    private void LifecycleEffect_Unloaded(object sender, System.EventArgs e)
    {
        if (sender == userName)
        {
            userNameLoaded = false;
        }
    }
    

    出现时 在iOS上后台+恢复后不会被调用,因此您需要连接到 Application.OnResume 如果用户后台+在iOS上恢复应用程序,则显示焦点:

    protected override void OnResume()
    {
        if (Xamarin.Forms.Device.RuntimePlatform == Xamarin.Forms.Device.iOS)
        {
            // TODO: Use Messenger, check Shell.Current.CurrentPage, etc. to set focus.
        }
    }
    
        6
  •  -3
  •   divyang4481    8 年前

    在Xamarin表单的下面是android活动或iOS的UIviewController的页面生命周期。一些条目。聚焦();在构造函数中不起作用