klingu
klingu

Reputation: 555

Scrollviewer with TextBoxes inside Pivot behavior make TextBoxes disappear under keybord

Does any body know a nice way to manage the behavior of the scrollviewer inside a PivotItem. While the Scrollviewer contains a Stackpannel with 6 TextBoxes and 6 TextBlockes. (See my code ferder below...)

The way I want it to work: No matter what Textbox I select... It should stay visible and all other textboxes should be reachable while the keybord is shown...

It is no problem if the header of the pivot disappears... But it would be nice if it stay on screan too... I've tried with margins, rectangles with dynamic hights, resizing of the RootFrame, resizing the Pivot, resizing the ViewScroller height... to make the it fit and work... I come close with the resizing actions. But the focus of the TextBox is sometimes behind the keybord.

How to manage to scroll/move the selected TextBox to the top of my screen in this situation...

I hope one of you can help me out...

Here my code of my XAML:

<Grid x:Name="LayoutRoot"
      Background="Transparent">

    <!--Pivot Control-->
    <phone:Pivot Title="MY APPLICATION"
                 x:Name="PivotRoot">
        <phone:PivotItem Header="first"
                         x:Name="PivotFirst">
            <ScrollViewer x:Name="Scroller">
                <StackPanel Background="Orange">

                    <TextBlock Text="hoi" />
                    <TextBox GotFocus="TextBlock_GotFocus_1"
                             LostFocus="TextBlock_LostFocus_1"></TextBox>
                    <TextBlock Text="hoi" />
                    <TextBox GotFocus="TextBlock_GotFocus_1"
                             LostFocus="TextBlock_LostFocus_1"></TextBox>
                    <TextBlock Text="hoi" />
                    <TextBox GotFocus="TextBlock_GotFocus_1"
                             LostFocus="TextBlock_LostFocus_1"></TextBox>
                    <TextBlock Text="hoi" />
                    <TextBox GotFocus="TextBlock_GotFocus_1"
                             LostFocus="TextBlock_LostFocus_1"></TextBox>
                    <TextBlock Text="hoi" />
                    <TextBox GotFocus="TextBlock_GotFocus_1"
                             LostFocus="TextBlock_LostFocus_1"></TextBox>

                </StackPanel>
            </ScrollViewer>
        </phone:PivotItem>
    </phone:Pivot>
</Grid>


<phone:PhoneApplicationPage.ApplicationBar>
    <shell:ApplicationBar x:Name="xxxx"
                          IsVisible="True"
                          IsMenuEnabled="True">
        <shell:ApplicationBarIconButton x:Name="appBarRegisterButton"
                                        IconUri="/Images/next.png"
                                        Text="Login"
                                        Click="appBarRegisterButton_Click_1"
                                        IsEnabled="True" />
    </shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>

Here my codebehind:

private void appBarRegisterButton_Click_1(object sender, EventArgs e)
    { }
private void TextBlock_GotFocus_1(object sender, RoutedEventArgs e)
    { }
private void TextBlock_LostFocus_1(object sender, RoutedEventArgs e)
    { }

Cheers,

K

Upvotes: 0

Views: 474

Answers (1)

klingu
klingu

Reputation: 555

The closest solution I was able to get is the following. The use of this solution managed in my flow of the application. It is not perfict yet. I'll say 95%... The biggest problem now is to manage the "dynamically appear and disappear" of the "Rectangle 'Keybordfiller'" I've used... I thought it was easy... unfortunately I didn't manage to make it happen... Feel free to use this and improve to make it happen... This will help a lot of people with this hard problem...

The MainPage.Xaml:

<phone:PhoneApplicationPage x:Class="PivotApp1.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"
                        d:DataContext="{d:DesignData SampleData/MainViewModelSampleData.xaml}"
                        FontFamily="{StaticResource PhoneFontFamilyNormal}"
                        FontSize="{StaticResource PhoneFontSizeNormal}"
                        Foreground="{StaticResource PhoneForegroundBrush}"
                        SupportedOrientations="Portrait"
                        Orientation="Portrait"
                        shell:SystemTray.IsVisible="True">

<Grid x:Name="LayoutRoot"
      Background="Transparent">

    <!--Pivot Control-->
    <phone:Pivot Title="MY APPLICATION"
                 x:Name="PivotRoot">
        <phone:PivotItem Header="first"
                         x:Name="PivotFirst">
            <ScrollViewer x:Name="Scroller">
                <StackPanel Background="Orange">
                    <TextBlock Text="hey" />
                    <TextBox GotFocus="TextBlock_GotFocus" />
                    <TextBlock Text="how" />
                    <TextBox GotFocus="TextBlock_GotFocus" />
                    <TextBlock Text="are" />
                    <TextBox GotFocus="TextBlock_GotFocus" />
                    <TextBlock Text="you" />
                    <TextBox GotFocus="TextBlock_GotFocus" />
                    <TextBlock Text="doing" />
                    <TextBox GotFocus="TextBlock_GotFocus" />
                    <Rectangle x:Name="Keybordfiller"
                               Height="350" />
                </StackPanel>
            </ScrollViewer>
        </phone:PivotItem>
    </phone:Pivot>
</Grid>

<phone:PhoneApplicationPage.ApplicationBar>
    <shell:ApplicationBar x:Name="Xxxx"
                          IsVisible="True"
                          IsMenuEnabled="True">
        <shell:ApplicationBarIconButton x:Name="AppBarRegisterButton"
                                        IconUri="/Assets/Tiles/IconicTileSmall.png"
                                        Text="Login"
                                        Click="appBarRegisterButton_Click"
                                        IsEnabled="True" />
    </shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>

The Code behind:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Navigation;

namespace PivotApp1
{
    public partial class MainPage 
    {
    public MainPage()
    {
        InitializeComponent();
        DataContext = App.ViewModel;
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        if (!App.ViewModel.IsDataLoaded)
        {
            App.ViewModel.LoadData();
        }
    }

    private void appBarRegisterButton_Click(object sender, EventArgs e)
    {
        //TODO: do some action with the button click
    }

    private void TextBlock_GotFocus(object sender, RoutedEventArgs e)
    {
        ScrollToControl((FrameworkElement)sender);
    }

    /// The issue to make it 100% fine For some reason it is not possible to make the Rectangle "Keybordfiller" Dynamically appear and disappear
    /// to have this issue solved...
    /// 
    /// When you use this code and manage to make it work 100%... 
    /// Please post your code/solution at: http://social.msdn.microsoft.com/Forums/en-US/wpdevelop/thread/b6fb4623-2fd3-459e-8c80-6ac2a77ee849/#a1f7d0fc-289c-40c9-8716-06e90c9dacd1
    /// 

    #region 90% fix of 'ScrollViewer with stackpannel full of Textboxes' handling in Pivot
    //TODO: Manage to make the Rectangle "Keybordfiller" appear and disappear Dynamically on the stackpannel

    private void ScrollToControl(FrameworkElement ui)
    {
        var currentoffset = Scroller.VerticalOffset;
        var y = GetVerticalOffset(ui, Scroller);
        Scroller.ScrollToVerticalOffset(y + currentoffset - 30);
        Scroller.UpdateLayout();
    }

    private double GetVerticalOffset(FrameworkElement child, ScrollViewer scrollViewer)
    {
        GeneralTransform focusedVisualTransform = child.TransformToVisual(scrollViewer);
        var topLeft = focusedVisualTransform.Transform(new Point(0, 0));
        return topLeft.Y;
    }

        #endregion
    }
}

I hope some one find the time to complete the functionality and make it Perfect ;-)

Cheers,

K

Upvotes: 2

Related Questions