如何在屏幕键盘打开时将控件滚动到WPF应用程序中的视图中?

时间:2018-01-22 09:08:43

标签: c# .net wpf windows-10

问题

如何在全屏模式下使用Windows10上的WPF应用程序并打开键盘(TabTip)时将当前(聚焦)控件滚动到视图中?

我拥有的是什么:

  • Windows 10 V10.0.16299.192 64位
  • .net 4.6.1
  • 经典WPF应用程序在没有窗口样式(以及最顶层)的情况下最大化
  • 平板电脑模式/桌面模式

到目前为止我尝试了什么:

  1. 从TabTip获取窗口句柄并获取有关窗口可见性和窗口高度的信息,以调整我的WPF窗口高度,以便在键盘可见时移动alle内容。 这工作于10.0.14393,直到Windows更新。

  2. 使用WPFTabTip自动键盘,当点击控件但不将控件滚动到视图中时会导致键盘频繁闪烁

  3. 问题

    • 我在WPF控件方面缺少什么,比如其他控件周围的滚动查看器,以便在键盘出现时启用滚动?
    • 当前窗口行为是不是将控件滚动到视图中只是一个将在未来的Windows更新中修复的错误?
    • 我是否需要更新到4.6.2并希望滚动在新版本中有效?

1 个答案:

答案 0 :(得分:0)

我也面临着同样的问题,这是我的解决方案:

VirtualKeyboardHelper.cs

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;

namespace YourNamespace
{
    /// <summary>
    /// Adjust parent control when child control got focus and virtual keyboard shown
    /// </summary>
    public class VirtualKeyboardHelper
    {
        bool _isParentAdjusted = false;

        const int DefaultShiftSize = 300;
        public int ShiftSize { get; set; } = DefaultShiftSize;

        [DllImport("user32.dll")]
        private static extern IntPtr FindWindow(String sClassName, String sAppName);

        static bool IsVirtualKeyboardShown()
        {
            var iHandle = (int)FindWindow("IPTIP_Main_Window", "");
            return (iHandle > 0);
        }

        private void DoSetAdjustmentOnFocus(UserControl owner, UIElement child)
        {            
            child.GotFocus += delegate
            {
                var m = owner.Margin;
                if (IsVirtualKeyboardShown())
                {
                    owner.Margin = new Thickness(m.Left, m.Top - ShiftSize, m.Right, m.Bottom);
                    _isParentAdjusted = true;
                }
            };

            child.LostFocus += delegate
            {
                var m = owner.Margin;
                if (_isParentAdjusted)
                    owner.Margin = new Thickness(m.Left, m.Top + ShiftSize, m.Right, m.Bottom);
            };
        }

        public static void SetAdjustmentOnFocus(UserControl owner, UIElement child, int shiftSize = DefaultShiftSize) 
            => new VirtualKeyboardHelper() { ShiftSize = shiftSize }.DoSetAdjustmentOnFocus(owner, child);

        public static void SetAdjustmentOnFocus(UserControl owner, List<UIElement> children)
        {
            foreach (var c in children)
                SetAdjustmentOnFocus(owner, c);
        }
    }
}

MyControl.cs

    public partial class MyControl : UserControl
    {        
        public MyControl()
        {
            InitializeComponent();

            // _textCity - is a TextBox defined in XAML
            VirtualKeyboardHelper.SetAdjustmentOnFocus(this, _textCity, 400);
            VirtualKeyboardHelper.SetAdjustmentOnFocus(this, _textState);
        }
    }

可以通过实现attched属性以在XAML中使用它来改进此解决方案。