Windows 8 当虚拟键盘打开时,以编程方式将控件滚动到视图中
我有一个垂直的文本框页面。如果其中一个已聚焦,则即使屏幕上显示了键盘,也应能看到所有的图像。它们的数量刚好足够,所有这些都可以放在键盘上方的可用空间中。当底部文本框聚焦时,页面会自动向上滚动,以便所有文本框都可见,但如果顶部文本框聚焦,屏幕键盘会覆盖底部文本框 这是我的页面的一个简化示例:Windows 8 当虚拟键盘打开时,以编程方式将控件滚动到视图中,windows-8,windows-runtime,winrt-xaml,Windows 8,Windows Runtime,Winrt Xaml,我有一个垂直的文本框页面。如果其中一个已聚焦,则即使屏幕上显示了键盘,也应能看到所有的图像。它们的数量刚好足够,所有这些都可以放在键盘上方的可用空间中。当底部文本框聚焦时,页面会自动向上滚动,以便所有文本框都可见,但如果顶部文本框聚焦,屏幕键盘会覆盖底部文本框 这是我的页面的一个简化示例: <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <ItemsControl Item
<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>
我已经尝试过几种方法,但都没有成功:
TextBox.GotFocus中,事件以编程方式将焦点更改为底部文本框并返回
TextBox.GotFocus
事件和输入窗格中。显示事件尝试设置ScrollViewer
的垂直偏移量:(a)我包含在网格周围的页面中的一个(b)Windows用于自动查看聚焦控件的页面上方视觉树中的一个。在这两种情况下,ScrollViewer
不会对ScrollToVerticalOffset
调用做出反应
我也看过中建议的,但它对屏幕键盘的反应不同,不是通过滚动页面。有时当您使用ScrollToVerticalOffset时,ScrollViewer不会自动刷新。
解决方法是在滚动后调用scrollviewer.UpdateLayout()。有好几种情况下它对我有效。多亏了Cyprient的回答,我终于成功地实现了这一点。我从我的问题中选择了选项2.a 添加
UpdateLayout()
调用是必需的,但当我将其放入GotFocus
事件处理程序时,它仅在虚拟键盘已经打开后才起作用。为了让它在键盘仍处于打开状态时第一次工作,我必须进行两项更改:
显示输入窗格事件的中
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();
});
}
很抱歉,我之前没有回复,但我最近一直忙于其他事情。虽然您的回答引导我朝着正确的方向前进,但我正在添加一个完整的解决方案,我已经在我的文章中更详细地描述了该解决方案。
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();
});
}
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;
}