3
votes

I have a screen which consists of several UI elements, mainly TextBoxes. When a TextBox gets focused whole page pushes up, moving the header outside the screen. I want the header to be at fixed position and the rest of the content to be pushed up inside a ScrollViewer. Ideally, I would like the offsets to be placed as intended and show/hide keyboard with correct focusing to the UI element. A good example to the correct scrolling behaviour is native Alarm app. Any help is appreciated. Cheers!

as hereas hereas here

2
I don't see anything different about the way the alarm app functions. It does exactly what you're saying you don't want it to do and pushes up everything. Can you try to clearly explain how the standard behavior doesn't work in your case, possibly with some code that demonstrates the behavior you want to change? - steveg89
It does not push up the header in alarm app but only evertyhing inside the scrollviewer under the header. I want to preserve the header when keyboard opens and shift the rest of the content like above. Normally I see that many apps wraps all layout content around a scrollviewer so the uppermost controls shifts outside the screen.How can we do that? (I cannot share the screen sorry due to legal issues but check any app and most of them are causing the same pushing outside screen when keyboard is active) - ilke.uygun

2 Answers

1
votes

When SIP keyboard is rendered, PhoneApplicationFrame.TranslateTransform.Y is set to specific values. To update layout, we’ll just set top margin to the specified value(-s) and after that Silverlight layout system will fix the issue.

here XAML part:

<Grid x:Name="LayoutRoot" >
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <StackPanel Grid.Row="0" Margin="12,17,0,28">
        <TextBlock Text="WINDOWS PHONE" Style="{StaticResource PhoneTextNormalStyle}"/>
        <TextBlock Text="developer's ?" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
    </StackPanel>
    <Grid Grid.Row="1" Margin="12,0,12,0"></Grid>
    <TextBox Grid.Row="2" LostFocus="TextBox_OnLostFocus" />
</Grid>

C# portions

public partial class MainPage : PhoneApplicationPage
{
    private static double newValue = 0.0;
    public static readonly DependencyProperty TranslateYProperty = DependencyProperty.Register("TranslateY", typeof(double), typeof(MainPage), new PropertyMetadata(0d, OnRenderXPropertyChanged));

    public MainPage()
    {
        InitializeComponent();
        this.Loaded += BindToKeyboardFocus;
    }

    private void BindToKeyboardFocus(object sender, RoutedEventArgs e)
    {
        PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
        if (frame != null)
        {
            var group = frame.RenderTransform as TransformGroup;
            if (group != null)
            {
                var translate = group.Children[0] as TranslateTransform;
                var translateYBinding = new Binding("Y");
                translateYBinding.Source = translate;
                SetBinding(TranslateYProperty, translateYBinding);
            }
        }
    }

    public double TranslateY
    {
        get { return (double)GetValue(TranslateYProperty); }
        set { SetValue(TranslateYProperty, value); }
    }

    private static void OnRenderXPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if ((double)e.NewValue <= newValue)
            ((MainPage)d).UpdateTopMargin((double)e.NewValue);
        newValue = (double)e.NewValue;
    }

    private void UpdateTopMargin(double translateY)
    {
        LayoutRoot.Margin = new Thickness(0, -translateY, 0, 0);
    }

    private void TextBox_OnLostFocus(object sender, RoutedEventArgs e)
    { 
        LayoutRoot.Margin = new Thickness();
    }
}

I think it will be helpful. Here is my GitHub link- https://github.com/rezacse/fixedHeaderOnTextBoxFocus

0
votes

I had the same issue. but at last i solved it, i just used the Height property to do this. Please do the following steps

  • First create a ScrollViewer
  • Indide the ScrollViewer create a container(eg: Grid/StackPanel/Border etc...) and put every controlls inside it.
  • Set fixed Height for ScrollViewer and the Container (Note: Height of container should be greater than ScrollViewer's Height)

See the below Code

<ScrollViewer Height="500">
        <Grid Name="Container" Height="700">
            <TextBox/>
            <TextBox/>
            <TextBox/>
        </Grid>
</ScrollViewer>

Now you can scroll the container Grid Even the KeyBoard shown or even focus on a TextBox. you can focus any text box and the ScrollViewer 'll not scroll back.