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

时间:2012-09-28 10:20:33

标签: windows-8 windows-runtime winrt-xaml

我有一个包含垂直文本框的页面。如果其中一个是聚焦的,即使显示屏幕键盘,所有这些都应该是可见的。只有足够的它们都适合键盘上方的可用空间。当底部文本框被聚焦时,页面会自动向上滚动,以便所有页面都可见,但如果顶部文本框被聚焦,屏幕键盘将覆盖底部文本框。

这是我页面的简化示例:

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <ItemsControl ItemsSource="{Binding List}" Margin="120 140 0 0">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" Margin="0 10 0 0">
                    <TextBox Text="{Binding Text, Mode=TwoWay}" />
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

DataContext包含10个项目的列表:

public class Item
{
    public string Text { get; set; }
}

public class ViewModel
{
    public List<Item> List { get; set; }
}

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

我已经尝试过几种方法,但都没有成功:

  1. TextBox.GotFocus事件中,以编程方式将焦点更改为底部文本框并返回。
  2. TextBox.GotFocus事件和InputPane.Showing事件尝试设置ScrollViewer的垂直偏移:(a)我在Grid(b)周围的页面中包含的那个Windows Page上方可视树中的一个,用于自动将聚焦控件置于视图中。在这两种情况下,ScrollViewer都不会对ScrollToVerticalOffset来电做出反应。
  3. 我还查看了sample中建议的this question,但它对屏幕键盘的反应不同,而不是通过滚动页面。

2 个答案:

答案 0 :(得分:8)

感谢Cyprient的回答,我终于设法让这个工作了。我从我的问题中追求选项2.a。

需要添加UpdateLayout()调用,但是当我将它放在GotFocus事件处理程序中时,它只在虚拟键盘已经打开后才能工作。为了让键盘第一次打开时,我不得不做两处更改:

  1. 我必须将代码放在Showing的{​​{1}}事件中。
  2. 我必须将它放在调度程序的回调中,以便只有在InputPane事件处理程序已经返回后才会调用它。
  3. 这是最终的代码:

    Showing

    这是我正在使用的辅助函数来获取对页面内容自动滚动时使用的相同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

答案 1 :(得分:3)

有时,当您使用ScrollToVerticalOffset时,ScrollViewer不会自行刷新。 解决方法包括在滚动后调用scrollviewer.UpdateLayout()。在几个案例中它对我有用。