当键盘处于活动状态时,ScrollViewer不会向上滚动

时间:2014-02-26 15:22:24

标签: windows-phone-8

如何在Windows Phone中获取表单行为,例如Contacts>>新联系人>>名称。在此页面中,它在scrollviewer中有许多文本框。当用户点击任何文本框并获得焦点时,页面向上滚动并且页眉保持不变并显示SIP键盘。 这是我的一个例子,但它不起作用

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

为什么呢? 谢谢

3 个答案:

答案 0 :(得分:1)

我修改了上面的代码,如下所示。

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

由于

答案 1 :(得分:0)

首先,为您的滚动查看器ScrollViewer命名。之后,为页面上的每个文本框控件添加GotFocusLostFocus事件处理程序,并在其中编写以下代码:

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

您需要将以下依赖项属性添加到页面中:

#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

还有辅助字段:

private double _oldHeight;
private TranslateTransform _translateTransform;

您还需要为滚动查看器处理一些事件,将其添加到页面的构造函数中:

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

实现这些事件处理程序:     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);
    }
}
哇,那里有很多代码。我正在努力创造可重复使用的东西,但我还没有。一旦我这样做,我将在NuGet上发布它。

请注意,这仅适用于Portrait模式,如果您打开了自动建议栏,则无法正常工作。我不需要在我的应用程序中处理它,所以我跳过它:)

享受。

答案 2 :(得分:0)

您可以尝试此示例sample project

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

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