【问题标题】:Why entry's Focus() method isn't working from page's constructor?为什么条目的 Focus() 方法在页面的构造函数中不起作用?
【发布时间】:2016-07-07 08:24:01
【问题描述】:

在 Xamarin Forms 中,当我使用以下代码时:

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

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

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

它根据需要工作(条目集中)。这是为什么?在InitializeComponent() 调用之后,codeEntry 不是已经存在并且功能齐全吗?我的意思是,我肯定可以从页面构造函数中更改Text 属性。

【问题讨论】:

    标签: xamarin xamarin.forms


    【解决方案1】:

    在 Xamarin 中,每个控件都有等效的视图渲染器,即原生 UI 元素,仅当控件添加到原生元素层次结构时才会创建。在构造函数中,尚未创建条目的本机元素。但是,在 OnAppering 中,会创建 entry 对应的 native 元素,以便获得焦点。

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

    【讨论】:

    • 这不是错误。请通过这个。 stackoverflow.com/questions/31169029/… .focus方法只能在控件创建并渲染后调用。
    • @AkashAmin 这是一个错误的原因,因为它可以通过维护状态并在 ViewRenderer 中创建本机元素时应用状态来轻松解决。
    【解决方案2】:

    当我使用 Shell 时,它不再起作用了。

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

    但这确实有效:

    protected async override void OnAppearing()
    {
         base.OnAppearing();
    
         await Task.Delay(100);
    
         someEntry.Focus();
    }
    

    【讨论】:

      【解决方案3】:

      文件.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】:

        我尝试了以上所有方法。我想是因为我的页面是一个弹出窗口并且有一些动画,以上都不起作用。然而这对我有用:

        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】:

          在 Xamarin 表单下面是 android 活动或 iOS 的 UIviewController 的页面生命周期工作。 someEntry.Focus();在您的构造函数中不起作用

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-12-10
            • 1970-01-01
            • 1970-01-01
            • 2014-08-24
            • 1970-01-01
            • 2019-04-30
            • 2022-07-29
            • 2013-08-24
            相关资源
            最近更新 更多