Scrollviewer & SIP Issue (WP7.5 Mango)

2020-08-16 05:32发布

I am working on an application which includes a registration form. The form contains multiple text entry boxes, and so a ScrollViewer is used to allow them all to be displayed on one page.

The following is a stripped down example of the XAML code I am using:

<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>

(Note that the ScrollViewer is inside a grid cell, which means that the title panel should stay OnScreen at all times)

The scrolling works perfectly fine, so that is not an issue. However, when the user selects a TextBox to enter data (i.e. the soft keyboard opens), the system pushes the content of the entire page around (including the registration title panel), which is not expected behaviour. [See the People app on Windows Phone and try adding a new contact. This contains a similar structure, but the ScrollViewer behaves correctly by only pushing content in the scrollviewer up]

Test Cases

  • Select a TextBox that is visible near the top of the screen, to open the keyboard.
  • Attempt to scroll to the bottom of the page with keyboard open.
  • Items at the bottom of the page are unreachable.

or

  • Select a TextBox that is visible near the bottom of the screen.
  • Content of entire page is pushed up.
  • Attempt to scroll to the top of the page with keyboard open.
  • Items at the top of the page are unreachable, and title panel never comes back into view until keyboard is closed.

Any help on resolving this issue would be appreciated. Thanks.

4条回答
甜甜的少女心
2楼-- · 2020-08-16 06:27

The problem is that the ScrollViwer height is not modified after the keyboard appears so it becomes clipped. One solution would be to modify the height of the scrollviwer (according to the keyboard height) and then reposition it (this might give you some headaches).

Another problem is knowing when the keyboard appears - you could register for the GotFocus/LostFocus events on all your TextBoxes but it's not a great solution. This might help you: http://blogs.msdn.com/b/jaimer/archive/2010/11/05/guessing-if-the-sip-is-visible-in-a-windows-phone-application.aspx

Hope this helps a little :)

查看更多
forever°为你锁心
3楼-- · 2020-08-16 06:27

I think you can solve this by coming at the problem from another angle. The phone will scroll up the page so that the SIP (software keyboard) never covers up the TextBox which has focus.

However you can force the SIP to hide by detecting touch events on the top element contained in your ScrollViewer, e.g.:

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

Then, by giving the focus to a hidden button (0x0 pixels in size) this will force the SIP to close. Then it will be possible for your users to scroll up and down the scrollviewer as expected...

    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();
    }
查看更多
冷血范
4楼-- · 2020-08-16 06:28

Have a look at my small library please - https://siphelper.codeplex.com/

It modifies height of scrollviewer and content can be scrolled to the topmost/bottommost point.

If you have any suggestions - feel free to contact me.

查看更多
爷的心禁止访问
5楼-- · 2020-08-16 06:32

I've had the same issue with an app I've developed and the way I dealt with it was to find out the auto height of the panel containing the input textboxs and then manually set the height and add approximately 400 - 500 px to the bottom to make it scroll nicely. The effect is quite smooth and will not make your UI look "hackish" IMHO.

In your case you will have to find out the automatic height of the LayoutRoot Grid and then on RowDefinitionof Row 1 set the height manually - remembering to add an extra 400px (or whatever looks appropriate in your situation).

For ease of input I then handled each OnKeyDown event of each TextBox to change the focus to the next TextBox upon hitting Enter. On the last TextBox I set the focus to this.focus() which sets focus to the Page and hides the SIP.

查看更多
登录 后发表回答