ScrollViewer does not scroll while keyboard is active

How can I get the behavior of the form in Windows Phone like Contacts β†’ New Contacts β†’ Name. On this page, it has many text fields in scrollviewer. When the user clicks on any text field and receives focus, the page scrolls up, and the title remains constant and the SIP keyboard is displayed. This is my example but not working

https://app.box.com/s/lxxcmxp8ckuottrweg52

Why? thanks

+2
source share
3 answers

I modified the above code, which works fine, as shown below.

public double OldHeight; private TranslateTransform _translateTransform; #region TranslateY dependency property public static readonly DependencyProperty TranslateYProperty = DependencyProperty.Register( "TranslateYProperty", typeof(double), typeof(Chat), new PropertyMetadata(default(double), PropertyChangedCallback)); private static void PropertyChangedCallback(DependencyObject o, DependencyPropertyChangedEventArgs e) { var chat = o as Chat; #if DEBUG Debug.WriteLine("New value:" + e.NewValue); Debug.WriteLine("Old value:" + e.OldValue); #endif if (chat != null) { chat.UpdateTopMargin((double)e.NewValue); } } public double TranslateY { get { return (double)GetValue(TranslateYProperty); } set { SetValue(TranslateYProperty, value); } } #endregion private void ChatPage_OnLoaded(object sender, RoutedEventArgs e) { var transform = ((Application.Current).RootVisual).RenderTransform as TransformGroup; if (transform != null) { _translateTransform = transform.Children.OfType<TranslateTransform>().FirstOrDefault(); if (_translateTransform != null) { var binding = new Binding("Y") { Source = _translateTransform }; BindingOperations.SetBinding(this, TranslateYProperty, binding); } } } private void UpdateTopMargin(double translateY) { LayoutRoot.Margin = new Thickness(0, -translateY, 0, 0); } 

thanks

+1
source

First name the scroll ScrollViewer . After that, add the GotFocus and LostFocus event handlers for each text field control on the page and write the following code inside:

 private void txt_LostFocus(object sender, RoutedEventArgs routedEventArgs) { ScrollViewer.Height = _oldHeight; } void txt_GotFocus(object sender, RoutedEventArgs e) { var transform = ((Application.Current).RootVisual).RenderTransform as TransformGroup; if (transform != null) { _translateTransform = transform.Children.OfType<TranslateTransform>().FirstOrDefault(); if (_translateTransform != null) { var binding = new Binding("Y") { Source = _translateTransform }; BindingOperations.SetBinding(this, TranslateYProperty, binding); } } var clipboardVisible = false; try { clipboardVisible = Clipboard.ContainsText(); } // ReSharper disable once EmptyGeneralCatchClause catch { } ScrollViewer.Height = _oldHeight - (clipboardVisible ? 407 : 338); } 

You will need to add the following dependency property to the page:

 #region TranslateY dependency property public static readonly DependencyProperty TranslateYProperty = DependencyProperty.Register( "TranslateYProperty", typeof(double), typeof(OrderContactPage), new PropertyMetadata(default(double), PropertyChangedCallback)); private static void PropertyChangedCallback(DependencyObject o, DependencyPropertyChangedEventArgs e) { ((OrderContactPage)o)._translateTransform.Y = 0; } public double TranslateY { get { return (double)GetValue(TranslateYProperty); } set { SetValue(TranslateYProperty, value); } } #endregion 

And also auxiliary fields:

 private double _oldHeight; private TranslateTransform _translateTransform; 

You also need to handle some events for your scroll viewer, add it to the page constructor:

 ScrollViewer.Loaded += ScrollViewerOnLoaded; ScrollViewer.SizeChanged += ScrollViewer_OnSizeChanged; 

Implement these event handlers: private void ScrollViewerOnLoaded (object sender, RoutedEventArgs routedEventArgs) {ScrollViewer.Loaded - = ScrollViewerOnLoaded; _oldHeight = ScrollViewer.ActualHeight; }

 private async void ScrollViewer_OnSizeChanged(object sender, SizeChangedEventArgs e) { await ScrollToFocusedElement(); } private async Task ScrollToFocusedElement() { await Task.Yield(); var focusedElement = FocusManager.GetFocusedElement() as PhoneTextBox; if (focusedElement != null) { // http://stackoverflow.com/questions/1225318/how-can-i-make-the-silverlight-scrollviewer-scroll-to-show-a-child-control-with var focusedVisualTransform = focusedElement.TransformToVisual(ScrollViewer); var rectangle = focusedVisualTransform.TransformBounds( new Rect(new Point(focusedElement.Margin.Left, focusedElement.Margin.Top), focusedElement.RenderSize)); var offset = ScrollViewer.VerticalOffset + (rectangle.Bottom - ScrollViewer.ViewportHeight); ScrollViewer.ScrollToVerticalOffset(offset); } } 

Wow, there is a lot of code. I am working on creating something reusable, but so far I haven't. As soon as I do this, I will publish it on NuGet.

Please note that this only works in Portrait mode and will not work perfectly if you have an automatic suggestion panel. I did not need to handle this in my application, so I skipped it :)

Enjoy.

0
source

you can try this sample project sample

 <Grid x:Name="LayoutRoot"> <Grid.RowDefinitions> <RowDefinition Height="60" /> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid Grid.Row="0" Background="#002080"> <TextBlock Text="PAGE HEADER" HorizontalAlignment="Center" VerticalAlignment="Center" /> </Grid> <Grid Grid.Row="1" /> <TextBox Grid.Row="2" Text="" x:Name="messageBox" Background="White" LostFocus="MessageBox_OnLostFocus" /> </Grid> public MainPage() { InitializeComponent(); this.Loaded += MainPage_Loaded; } 

closed static double _newValue;

  private static readonly DependencyProperty TranslateYProperty = DependencyProperty.Register("TranslateY", typeof(double), typeof(MainPage), new PropertyMetadata(0d, OnRenderXPropertyChanged)); private double TranslateY { get { return (double)GetValue(TranslateYProperty); } } 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 BindToKeyboardFocus() { var frame = Application.Current.RootVisual as PhoneApplicationFrame; if (frame == null) return; var group = frame.RenderTransform as TransformGroup; if (@group == null) return; var translate = @group.Children[0] as TranslateTransform; var translateYBinding = new Binding("Y") { Source = translate }; SetBinding(TranslateYProperty, translateYBinding); } private void UpdateTopMargin(double translateY) { double prevTopMargin = LayoutRoot.Margin.Top; LayoutRoot.Margin = new Thickness(0, -translateY, 0, 0); } 
0
source

All Articles