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