Question

I have a problem with scrolling in windows phone. I have a lot of elements on page so to add ability to scroll I put this on ScrollViewer. Hovewer, when I foucesd on some text block and the keyborad shows up, the scroll in working but it cuts the top and bottom of the page so it's can't be reach by user. Have you had similar problem with your apps and know how to fix this ?

I wil be really grateful for any help


Link to image when I put screenshot with my problem

The picture contains four screenshots:

1) The top of the page

2) The bottom of the page

3) Focus on the first textbox

4) The area on the page which can be reached when focus is set to the first TextBox

The last one picture present the are which can be rached when focus is set to the first textbox. As you can see I can't get to the textboxes below Field 7 when keybord is shown.

What I need is the ability to scroll and to reach all elements when the keybord is shown.

Do you know how to resolve my poblem


It's my xaml code:

<phone:PhoneApplicationPage
    x:Class="PhoneApp6.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <ScrollViewer Grid.Row="1" Height="600" Margin="12 0">
            <StackPanel>
                <StackPanel>
                    <TextBlock  Text="Name 1" />
                    <TextBox  />
                </StackPanel>

                <StackPanel>
                    <TextBlock  Text="Name 2" />
                    <TextBox  />
                </StackPanel>

                <StackPanel>
                    <TextBlock  Text="Name 3" />
                    <TextBox  />
                </StackPanel>

                <StackPanel>
                    <TextBlock  Text="Name 4" />
                    <TextBox  />
                </StackPanel>

                <StackPanel>
                    <TextBlock  Text="Name 5" />
                    <TextBox  />
                </StackPanel>

                <StackPanel>
                    <TextBlock  Text="Name 6" />
                    <TextBox  />
                </StackPanel>

                <StackPanel>
                    <TextBlock  Text="Name 7" />
                    <TextBox  />
                </StackPanel>

                <StackPanel>
                    <TextBlock  Text="Name 8" />
                    <TextBox  />
                </StackPanel>

                <StackPanel>
                    <TextBlock  Text="Name 9" />
                    <TextBox  />
                </StackPanel>

                <StackPanel>
                    <TextBlock  Text="Name 10" />
                    <TextBox  />
                </StackPanel>

                <Button>Submit</Button>
            </StackPanel>
        </ScrollViewer>
    </Grid>

</phone:PhoneApplicationPage>
Was it helpful?

Solution

This is a known issue and is caused by the SIP changing the viewable area of the screen. The link David Gorden mentioned does help, but you actually need to change the height of the scrollviewer to achieve perfect results. To make things a little more complex WP does not trigger an event for when the SIP is visible! So you need to hook into the GotFocus/LostFocus events.

Edit your scrollviewer so it looks something like this:

<ScrollViewer x:Name="_scrollViewer"
                  VerticalAlignment="Top"
                  GotFocus="UIElement_OnGotFocus"
                  LostFocus="UIElement_OnLostFocus" 
                  ... bla bla

Now add the following in the codebehind:

private bool _isHdDevice;
    private int _sipHeight;
    private double _origHeight;

    // Constructor
    public MainPage()
    {
        InitializeComponent();

        // todo - cater for landscape mode or sip scopenames that require extra space (predictive text and cut&paste icon)
        var deviceWidth = this.ActualWidth;
        _isHdDevice = (deviceWidth > 500);
        _sipHeight = _isHdDevice ? 540 : 375;
        _origHeight = _scrollViewer.Height;
    }

    private void UIElement_OnGotFocus(object sender, RoutedEventArgs e)
    {
        double height = this.ActualHeight - _sipHeight - TitlePanel.ActualHeight;
        _scrollViewer.Height = height;
        // the following lines are crucial otherwise a black band could appear above the SIP
        App.Current.RootVisual.RenderTransform = new CompositeTransform();
        this.UpdateLayout();
    }

    private void UIElement_OnLostFocus(object sender, RoutedEventArgs e)
    {
        _scrollViewer.Height = _origHeight;
    }

This is basically resizing the scroll area when the sip (keyboard) is in view. You will need to add more code to cater for things like screen rotation, scopename associated to the textbox, and cut&paste icon if in view. But this will get you going and does the difficult bit.

Please mark as answered if it helped fix the issue.

OTHER TIPS

If I understand this correctly, I was having a similar problem in my own app with an inability to scroll downward to the lowest texboxes while the keyboard is visible. Since I'm not all that clever, I solved it in the following way: a spacer that appears when the keyboard is up and disappears when it's not.

The textbox items for input in my scrollviewer are all in wrappanels, to keep things tidy. Below the last wrap panel, I added another, empty wrap panel, named "spacer" with a height of 120. It is set to visibility.collapsed by default.

As part of the gotfocus event handler for each of the textboxes in the wrap panel, I set spacer to visible. That allows for scrolling all the way to the last wrappanel/textboxes in my scroll viewer while the keyboard is up.

As a part of my lostfocus event handler for each of the textboxes, spacer's visibility is set back to "collapsed." That way, when there's no keyboard up, the scrollviewer doesn't have a big, funky, empty space at the bottom.

This may not be so elegant, but it's easy and works pretty well for me. I have not yet encountered any problems with it, though that doesn't mean there may not be something I've missed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top