且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

当虚拟键盘打开时,以编程方式将控件滚动到视图中

更新时间:2023-10-30 13:59:58

多亏了 Cyprient 的回答,我终于设法让它发挥作用.我从我的问题中选择了选项 2.a.

Thanks to Cyprient's answer I finally managed to get this to work. I pursued option 2.a from my question.

添加 UpdateLayout() 调用是必需的,但是当我将它放入 GotFocus 事件处理程序时,它仅在虚拟键盘已经打开后才起作用.为了让它在键盘仍然打开的时候第一次工作,我不得不做两个改变:

Adding UpdateLayout() call was required, but when I put it in the GotFocus event handler it only worked after the virtual keyboard was already opened. To make it work the first time when the keyboard was still opening, I had to make two changes:

  1. 我不得不将代码放在 InputPaneShowing 事件中.
  2. 我必须将它放在调度程序的回调中,以便仅在 Showing 事件处理程序返回后才调用它.
  1. I had to put the code in the Showing event of InputPane.
  2. I had to put it in a callback for the dispatcher so that it was called only after the Showing event handler had already returned.

这是最终代码:

public MainPage()
{
    this.InitializeComponent();
    DataContext = new ViewModel
    {
        List = Enumerable.Range(0, 10).Select(i => new Item { Text = i.ToString() }).ToList()
    };

    var inputPane = InputPane.GetForCurrentView();
    inputPane.Showing += InputPane_Showing;
}

private async void InputPane_Showing(InputPane sender, InputPaneVisibilityEventArgs args)
{
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        {
            var parentScrollViewer = FindParent<ScrollViewer>(this.pageRoot);
            parentScrollViewer.VerticalScrollMode = ScrollMode.Enabled;
            parentScrollViewer.ScrollToVerticalOffset(65);
            parentScrollViewer.UpdateLayout();
        });
}

这是我用来获取对相同 ScrollViewer 的引用的辅助函数,该函数在页面内容自动滚动时使用,否则将不会显示焦点控件:

Here's the helper function I'm using to get the reference to the same ScrollViewer which is used when the page contents gets scrolled automatically because the focused control would not be shown otherwise:

public static T FindParent<T>(FrameworkElement reference)
    where T : FrameworkElement
{
    FrameworkElement parent = reference;
    while (parent != null)
    {
        parent = parent.Parent as FrameworkElement;

        var rc = parent as T;
        if (rc != null)
        {
            return rc;
        }
    }

    return null;
}