我有一个带有一组垂直文本框的页面。如果其中之一获得焦点,则即使显示屏幕键盘,所有这些都应该可见。它们的数量刚好足以容纳键盘上方的可用空间。当底部文本框获得焦点时,页面会自动向上滚动,以便所有文本框都可见,但如果顶部文本框获得焦点,屏幕键盘会覆盖底部文本框。
这是我的页面的简化示例:
<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()
};
}
我已经尝试了几种方法,但都没有成功:
- 在
TextBox.GotFocus
事件中以编程方式将焦点更改为底部文本框并返回。 - 在
TextBox.GotFocus
事件和InputPane.Showing
事件中尝试设置ScrollViewer
的垂直偏移:(a) 我包含的那个在Grid
周围的页面中 (b) 视觉树中Page
上方的一个,Windows 使用它自动将焦点控件带入 View 。在这两种情况下,ScrollViewer
不会对ScrollToVerticalOffset
调用使用react。
我还查看了 sample this question中建议但它对屏幕键盘的 react 不同,而不是通过滚动页面。
最佳答案
感谢 Cyprient 的回答,我终于成功地让它发挥作用。我从问题中选择了选项 2.a。
需要添加 UpdateLayout()
调用,但是当我将其放入 GotFocus
事件处理程序中时,它仅在虚拟键盘已打开后才起作用。为了使其在键盘仍然打开时第一次工作,我必须进行两项更改:
- 我必须将代码放入
InputPane
的Showing
事件中。 - 我必须将其放入调度程序的回调中,以便仅在
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
的引用的辅助函数,该函数在页面内容自动滚动时使用,因为否则不会显示聚焦控件:
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;
}
关于windows-8 - 当虚拟键盘打开时,以编程方式将控件滚动到 View 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12638117/