【问题标题】:Soft keyboard overlaps TextBoxes and makes them unreachable软键盘与文本框重叠并使其无法访问
【发布时间】:2015-02-02 12:29:13
【问题描述】:

当输入字段被软键盘重叠时,如何到达 ScrollViewer 中的输入字段?

这个场景很容易重现:

  1. 使用包含一些文本框的 ScrollViewer 创建一个新页面。根据需要制作尽可能多的文本框,直到您需要滚动页面以到达最后三个文本框。

    <ScrollViewer>
      <StackPanel Orientation="Vertical">
        <TextBox Margin="20" />
        <TextBox Margin="20" />
        <TextBox Margin="20" />
        ..
        <TextBox Margin="20" />
        <TextBox Margin="20" />
        <TextBox Margin="20" PlaceholderText="3" />
        <TextBox Margin="20" PlaceholderText="2" />
        <TextBox Margin="20" PlaceholderText="1" />
      </StackPanel>
    </ScrollViewer>
    
  2. 启动应用程序并点击“Placeholder 3”。键盘弹出并与“Paceholder 2”和“Placeholder 1”重叠。

如何改进布局,以便无需一直关闭和重新打开键盘就可以访问这些文本框(“1”和“2”)?

可以在每个 WindowsPhone 上找到一个显示有效解决方案的示例:设置 => VPN => 启用 VPN => 添加新配置文件 => 单击任何文本框,您会看到可以滚动到每个部分尽管软键盘已启动,但布局的变化。

【问题讨论】:

  • Keyboard overlaps textbox 的可能重复项
  • 不知何故,它们是相关的,是的。但就我而言,我并没有改变焦点,只是想在键盘周围和上方滚动完整的布局。
  • 你仍然需要滚动到垂直偏移来否定键盘的高度并将内容提供到滚动查看器视口的可用空间中,这个概念基本上是相同的你的问题和那个问题一样。
  • 链接的问题也适用于 WP8,我的问题适用于 WP8.1。就我而言,没有可翻译的 Application.Current.RootVisual 。我用谷歌搜索了一下,但找不到任何替代属性。它可以与 Window.Current.CoreWindow 一起使用吗?但是我该如何翻译呢?
  • 我发现这是 y 平移偏移量:social.msdn.microsoft.com/Forums/windowsapps/en-US/… 但是当键盘打开时我仍然无法滚动到任何我想要的位置。过度滚动效果总是在我接近布局的上端之前就开始了。

标签: c# xaml keyboard windows-phone-8.1 scrollviewer


【解决方案1】:

在这个问题上已经有一段时间了,但对于可能正在寻找一个好的解决方案的其他人来说,我就是这样做的。

订阅键盘显示和隐藏事件,并根据键盘显示或隐藏的时间调整滚动查看器的高度。

Xaml

<ScrollViewer x:Name="scrlvwrKBScroll" VerticalScrollMode="Enabled">
  <StackPanel Orientation="Vertical">
    <TextBox Margin="20" />
    <TextBox Margin="20" />
    <TextBox Margin="20" />
    ..
    <TextBox Margin="20" />
    <TextBox Margin="20" />
    <TextBox Margin="20" PlaceholderText="3" />
    <TextBox Margin="20" PlaceholderText="2" />
    <TextBox Margin="20" PlaceholderText="1" />
  </StackPanel>
</ScrollViewer>

C#

public Constructor()
{
  this.InitializeComponent()
  InputPane.GetForCurrentView().Showing += Keyboard_OnShow;
  InputPane.GetForCurrentView().Hiding += Keyboard_OnHide;
}

private void Keyboard_OnShow(InputPane sender, InputPaneVisibilityEventArgs args)
{
  this.scrllvwrKBScroll.Height = this.ActualHeight - args.OccludedRect.Height - 50;
}

private void Keyboard_OnHide(InputPane sender, InputPaneVisibilityEventArgs args)
{
  this.scrllvwrKBScroll.height = this.ActualHeight;
}

可能有更好的方法可以根据您正在使用的容器的高度调整高度,但这是我用来让我的应用程序工作的方法。

【讨论】:

    【解决方案2】:

    每当带有BottomAppBarPage 在布局中从根视觉中移位时,我也会遇到此问题。这可能是由包装元素上的 MarginPadding 引起的。

    损坏的视觉树:

    • Window.Current.ContentFrame
      • Border 1px Margin
        • ContentPresenter
          • PageBottomAppBar

    我找不到“不恶心”的解决方法,但是直接在根 ScrollViewer 上调整偏移量确实对我有用。请参阅 UWPMobileScrollIssue 了解完整的重现和解决方法。

    // ...snip...
    namespace UWPFocusTestApp
    {
        sealed partial class App : Application
        {
            // ...snip...
            protected override void OnLaunched(LaunchActivatedEventArgs e)
            {
                // ...snip...
                if (rootFrame == null)
                {
                    // ...snip...
    
                    // Place the frame in the current Window
                    Window.Current.Content = rootFrame;
    
                    #region WORKAROUND
                    if (AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.Mobile")
                    {
                        InputPane.GetForCurrentView().Showing += InputPane_Showing;
                    }
                    #endregion
                }
    
                // ...snip...
            }
    
            #region WORKAROUND
            private void InputPane_Showing(InputPane sender, InputPaneVisibilityEventArgs args)
            {
                // we only need to hook once
                InputPane.GetForCurrentView().Showing -= InputPane_Showing;
    
                var frame = (Frame)Window.Current.Content;
    
                // Find root ScrollViewer
                DependencyObject cNode = frame;
                while (true)
                {
                    var parent = VisualTreeHelper.GetParent(cNode);
                    if (parent == null)
                    {
                        break;
                    }
                    cNode = parent;
                }
                var rootScrollViewer = (ScrollViewer)cNode;
    
                // Hook ViewChanged to update scroll offset
                bool hasBeenAdjusted = false;
                rootScrollViewer.ViewChanged += (_1, svargs) =>
                {
                    // once the scroll is removed, clear flag
                    if (rootScrollViewer.VerticalOffset == 0)
                    {
                        hasBeenAdjusted = false;
                        return;
                    }
                    // if we've already adjusted, bail.
                    else if (hasBeenAdjusted)
                    {
                        return;
                    }
    
                    var appBar = ((Page)frame.Content)?.BottomAppBar;
                    if (appBar == null)
                    {
                        return;
                    }
    
                    hasBeenAdjusted = true;
                    rootScrollViewer.ChangeView(null, rootScrollViewer.VerticalOffset + appBar.ActualHeight, null);
                };
            }
            #endregion
    
            // ...snip...
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-14
      • 2012-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多