Scrollviewer & SIP Issue (WP7.5 Mango)

Я работаю над приложением, которое включает регистрационную форму. Форма содержит несколько текстовых полей ввода, поэтому 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 находится внутри ячейки сетки, что означает, что панель заголовка должна оставаться OnScreen в любое время)

Прокрутка работает отлично, так что это не проблема. Однако, когда пользователь выбирает TextBox для ввода данных (т.е. Открывается мягкая клавиатура), система подталкивает содержимое всей страницы вокруг (включая панель заголовка регистрации), что не является ожидаемым поведением. [См. Приложение "Люди" на Windows Phone и попробуйте добавить новый контакт. Это содержит аналогичную структуру, но ScrollViewer ведет себя правильно, только нажав содержимое в scrollviewer вверх]

Тест-тесты

  • Выберите текстовый блок, который отображается в верхней части экрана, чтобы открыть клавиатуру.
  • Попытка прокрутки в нижней части страницы с открытой клавиатурой.
  • Элементы внизу страницы недоступны.

или

  • Выберите текстовый блок, который будет виден в нижней части экрана.
  • Содержимое всей страницы задвинуто.
  • Попытка прокрутки вверху страницы с открытой клавиатурой.
  • Элементы в верхней части страницы недоступны, и панель заголовка никогда не возвращается в поле зрения, пока клавиатура не будет закрыта.

Любая помощь в решении этой проблемы будет оценена по достоинству. Спасибо.

Ответ 1

Проблема заключается в том, что высота ScrollViwer не изменяется после появления клавиатуры, поэтому она обрезается. Одним из решений было бы изменить высоту scrollviwer (в соответствии с высотой клавиатуры), а затем переместить его (это может вызвать некоторые головные боли).

Еще одна проблема - знать, когда появляется клавиатура - вы можете зарегистрироваться для событий GotFocus/LostFocus во всех своих текстовых блоках, но это не отличное решение. Это может помочь вам: http://blogs.msdn.com/b/jaimer/archive/2010/11/05/guessing-if-the-sip-is-visible-in-a-windows-phone-application.aspx

Надеюсь, это немного поможет:)

Ответ 2

Я думаю, что вы можете решить это, зайдя на проблему под другим углом. Телефон будет прокручивать страницу таким образом, чтобы SIP (программная клавиатура) никогда не закрывала TextBox с фокусом.

Однако вы можете заставить SIP скрыть, обнаружив события касания на верхнем элементе, содержащемся в вашем ScrollViewer, например:

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

Затем, выделив фокус на скрытую кнопку (размером 0x0 пикселей), это заставит SIP закрыть. Затем ваши пользователи смогут прокручивать вверх и вниз по scrollviewer, как ожидалось...

    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();
    }

Ответ 3

У меня была такая же проблема с приложением, которое я разработал, и с тем, как я занимался этим, это выяснить автоматическую высоту панели, содержащей вход textbox, а затем вручную установить высоту и добавить примерно 400 - 500 пикселей снизу, чтобы сделать прокрутку красиво. Эффект довольно плавный и не заставит ваш пользовательский интерфейс выглядеть "хакерским" IMHO.

В вашем случае вам нужно будет узнать автоматическую высоту LayoutRoot Grid, а затем в RowDefinition строки Row 1 задайте высоту вручную - не забудьте добавить дополнительный 400px (или что-то, что вам подходит ситуация).

Для удобства ввода я обработал каждое событие OnKeyDown каждого textbox, чтобы изменить фокус на следующий textbox при нажатии Enter. В последнем textbox я установил фокус на this.focus(), который устанавливает фокус на страницу и скрывает SIP.

Ответ 4

Посмотрите на мою небольшую библиотеку, пожалуйста - https://siphelper.codeplex.com/

Он изменяет высоту scrollviewer, и содержимое можно прокручивать до самой верхней/нижней точки.

Если у вас есть предложения - не стесняйтесь обращаться ко мне.