滚动视图器和SIP问题(WP7.5 Mango)

10

我正在开发一个应用程序,其中包含一个注册表单。该表单包含多个文本输入框,因此使用ScrollViewer可以让它们都在同一页上显示。

以下是我正在使用的XAML代码的简化示例:

<Grid x:Name="LayoutRoot" Background="Transparent">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
        <TextBlock x:Name="ApplicationTitle" Text="SCROLLVIEWER TEST" Style="{StaticResource PhoneTextNormalStyle}"/>
        <TextBlock x:Name="PageTitle" Text="registration" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
    </StackPanel>

    <ScrollViewer Grid.Row="1">
        <StackPanel>
            <TextBlock Text="Hello" Margin="12,0,0,0"/>
            <TextBox />
            <TextBlock Text="Hello1" Margin="12,0,0,0"/>
            <TextBox />
            <TextBlock Text="Hello2" Margin="12,0,0,0"/>
            <TextBox />
            <TextBlock Text="Hello3" Margin="12,0,0,0"/>
            <TextBox />
            <TextBlock Text="Hello4" Margin="12,0,0,0"/>
            <TextBox />
            <TextBlock Text="Hello5" Margin="12,0,0,0"/>
            <TextBox />
            <TextBlock Text="Hello6" Margin="12,0,0,0"/>
            <TextBox />
            <TextBlock Text="Hello7" Margin="12,0,0,0"/>
            <TextBox />
            <TextBlock Text="Hello8" Margin="12,0,0,0"/>
            <TextBox />
            <TextBlock Text="END" Margin="12,0,0,0"/>
            <TextBox />
        </StackPanel>
    </ScrollViewer>
</Grid>

请注意,ScrollViewer在网格单元格内部,这意味着标题面板应始终保持在屏幕上。

滚动功能完全正常,不是问题。但是,当用户选择文本框以输入数据(即软键盘打开)时,系统会将整个页面的内容(包括注册标题面板)推到周围,这不是预期的行为。 [请参见Windows Phone上的People应用程序,并尝试添加新联系人。它包含类似的结构,但是ScrollViewer正确地通过仅向上推动滚动视图器中的内容来推动内容]

测试用例

  • 选择靠近屏幕顶部的可见文本框,以打开键盘。
  • 尝试使用打开的键盘向页面底部滚动。
  • 页面底部的项目无法访问。

或者

  • 选择靠近屏幕底部的可见文本框。
  • 整个页面的内容被推上。
  • 尝试使用打开的键盘向页面顶部滚动。
  • 页面顶部的项目无法访问,标题面板直到关闭键盘后才会重新出现。

希望能够得到解决此问题的任何帮助。谢谢。


以下博客文章可能是解决此问题的好起点:http://sorokoletov.com/2011/08/windows-phone-70-handling-text-entry-screens/ - Paul Diston
@PaulDiston 谢谢。我之前已经阅读过这篇博客。我尝试了演示应用程序,但它并不是我想要的。转换非常突兀(即当SIP动画完成时,标题面板会重新出现),更不用说实现对于如此简单的东西来说过于复杂了。我的预期实现是与“People”应用程序中包含的用于管理联系人和地址的联系人详细信息表单相匹配。这不是一个复杂的例子,人们希望这可以直接使用而不需要覆盖表单中的项目。 - Jason H
如果可以帮助滚动问题,请尝试这个。http://www.luisleo.net/2012/06/24/how-to-use-listbox-properly-with-windows-phone-7/ - 123 456 789 0
4个回答

0

我认为你可以从另一个角度来解决这个问题。手机将向上滚动页面,以便SIP(软件键盘)永远不会覆盖具有焦点的文本框。

但是,您可以通过检测包含在ScrollViewer中的顶部元素的触摸事件来强制隐藏SIP,例如:

<ScrollViewer Grid.Row="1">
    <StackPanel ManipulationDelta="OnScrollViewerGridManipulationDelta">`

接着,通过将焦点放在一个隐藏的按钮上(大小为0x0像素),这将强制关闭SIP。然后,您的用户就可以按预期在滚动查看器中上下滚动了...

    private void OnScrollViewerGridManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e)
    {
        // This will hide the SIP if it is currently showing. 
        // We can't do this directly, but we can force this by taking focus away from any of the TextBoxes that may have it.
        this.hiddenButton.Focus();
    }

你可以在代码后台中调用this.Focus()来将焦点放在页面上,以隐藏SIP。不需要创建额外的隐藏对象。 - Styff

0
问题在于键盘出现后,ScrollViwer的高度没有被修改,因此会被裁剪。一个解决方案是根据键盘的高度修改Scrollviwer的高度,然后重新定位它(这可能会让你头疼)。
另一个问题是如何知道键盘何时出现 - 你可以注册所有TextBoxes的GotFocus/LostFocus事件,但这不是一个好的解决方案。这可能会帮助你:http://blogs.msdn.com/b/jaimer/archive/2010/11/05/guessing-if-the-sip-is-visible-in-a-windows-phone-application.aspx 希望这能有所帮助 :)

听起来像是可行的黑客攻击。但是,这仅在您选择屏幕顶部的框时才有效(当滚动查看器底部的内容被遮挡时)。文本框在屏幕上的物理位置会影响页面向上推的程度。因此,如果它在顶部,内容只会被轻微地推上去。如果它在底部,内容将被推得非常远。据我所知,无法确定页面调整了多少,这意味着很难进行整洁的补偿。此外,标题窗格将继续被推出屏幕,这并不理想。 - Jason H

0

我曾经开发的一个应用程序也遇到了同样的问题,我的解决方法是找出包含输入文本框的面板的自动高度,然后手动设置高度并在底部添加大约400-500像素以使其滚动得很好。效果非常流畅,不会让您的用户界面看起来“hackish”。

在您的情况下,您需要找出LayoutRoot Grid的自动高度,然后在第1行的RowDefinition上手动设置高度 - 记住要添加额外的400像素(或者根据您的情况适当调整)。

为了方便输入,我处理了每个TextBoxOnKeyDown事件,以在按下Enter时将焦点更改为下一个TextBox。在最后一个TextBox上,我将焦点设置为this.focus(),这将把焦点设置为页面并隐藏SIP。


0
请查看我的小型库 - https://siphelper.codeplex.com/ 它可以修改滚动视图器的高度,内容可以滚动到最上方或最下方。
如果您有任何建议,请随时与我联系。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接