软键盘重叠控制(WPF,桌面)

时间:2014-07-01 19:31:43

标签: c# .net wpf desktop-application

首先我想强调一下,我正在寻找一个 Windows DESKTOP WPF 解决方案,所以请不要安卓。谢谢。

其次,我是WPF的新手,并为Windows平板电脑设计软件,所以请耐心等待......请明确答案。

第三,目标软件将在Windows平板电脑(Win 8.0 / 8.1)上运行,并且正在使用Visual Studio 2013 Pro(C#,桌面应用程序,WPF)进行开发。

好的,这是我的问题:

当用户触摸文本框时,我一直在使用Textbox继承类来显示软键盘(类代码如下)。这部分实际上运作良好。 我的问题是软键盘可能会弹出我的实际控件。在WinRT中,这不会发生,因为操作系统似乎滚动所述控件直到它变得可见,但是使用DESKTOP应用程序时不存在这样的功能。

所以我的问题是:有没有人知道如何解决这个重叠问题?

我怎么能(在Win桌面应用程序中)复制正常的WinRT行为?

我应该使用其他API来调用软键盘吗?

“TouchTextbox”类的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;

namespace WPF_DT_Soft_Keyboard
{
    class TouchTextbox : TextBox 
    {

        [DllImport("user32.dll")]
        public static extern int FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);

        public const int WM_SYSCOMMAND = 0x0112;
        public const int SC_CLOSE = 0xF060;        

        protected override void OnGotFocus(System.Windows.RoutedEventArgs e)
        {
            base.OnGotFocus(e);
            ShowSoftKeyboard();
        }

        protected override void OnLostFocus(System.Windows.RoutedEventArgs e)
        {
            base.OnLostFocus(e);
            HideSoftKeyboard();
        }

        protected override void OnPreviewKeyUp(System.Windows.Input.KeyEventArgs e)
        {
            base.OnPreviewKeyUp(e);
            if (e.Key == System.Windows.Input.Key.Enter) HideSoftKeyboard();
        }

        private void ShowSoftKeyboard()
        {
            System.Diagnostics.Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");
        }

        private void HideSoftKeyboard()
        {
            int iHandle = FindWindow("IPTIP_Main_Window", "");
            if (iHandle > 0)
            {
                SendMessage(iHandle, WM_SYSCOMMAND, SC_CLOSE, 0);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

好的,我想我终于找到了一个不错的解决方案。 我把它封装在下面的TouchTextbox类中。 要使其正常工作,TouchTextbox必须包含[ScrollViewer]控件。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Controls;
    using System.Windows.Threading;

    namespace WPF_DT_Soft_Keyboard
    {
        class TouchTextbox : TextBox 
        {

        /// <summary>
        /// Private Container
        /// </summary>
        DispatcherTimer mBringIntoViewTimer = new DispatcherTimer();

        /// <summary>
        ///  DLL imports
        /// </summary>
        [DllImport("user32.dll")]
        public static extern int FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll")]
        public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);
        [DllImport("user32.dll")]
        public static extern int MoveWindow(int hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
        [DllImport("user32.dll")]
        public static extern int SetWindowPos(int hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
        [DllImport("Kernel32.dll")]
        public static extern uint GetLastError();

        /// <summary>
        /// Constante
        /// </summary>
        public const int WM_SYSCOMMAND = 0x0112;
        public const int SC_CLOSE = 0xF060;
        public const int HWND_TOP = 0;
        public const int SWP_NOSIZE = 0x0001;
        public const int SWP_NOZORDER = 0x0004;
        public const int SWP_SHOWWINDOW = 0x0040;
        public const int BRING_INTO_VIEW_DELAY = 500;


        /// <summary>
        /// TouchTextbox
        /// </summary>
        public TouchTextbox()
        {
            mBringIntoViewTimer.IsEnabled = false;
            mBringIntoViewTimer.Tick += MyTimer_Tick;
            mBringIntoViewTimer.Interval = new TimeSpan(0, 0, 0, 0, BRING_INTO_VIEW_DELAY);
        }

        /// <summary>
        /// MyTimer_Tick
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MyTimer_Tick(object sender, EventArgs e)
        {
            mBringIntoViewTimer.IsEnabled = false;
            this.BringIntoView();
        }

        /// <summary>
        /// OnGotFocus
        /// </summary>
        /// <param name="e"></param>
        protected override void OnGotFocus(System.Windows.RoutedEventArgs e)
        {
            base.OnGotFocus(e);
            ShowSoftKeyboard();
            mBringIntoViewTimer.IsEnabled = true;
        }

        ///// <summary>
        ///// OnLostFocus
        ///// </summary>
        ///// <param name="e"></param>
        //protected override void OnLostFocus(System.Windows.RoutedEventArgs e)
        //{
        //    base.OnLostFocus(e);
        //    HideSoftKeyboard();
        //}

        /// <summary>
        /// OnPreviewKeyUp
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPreviewKeyUp(System.Windows.Input.KeyEventArgs e)
        {
            base.OnPreviewKeyUp(e);
            if (e.Key == System.Windows.Input.Key.Enter) HideSoftKeyboard();
        }

        /// <summary>
        /// ShowSoftKeyboard
        /// </summary>
        private void ShowSoftKeyboard()
        {
            Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\TabletTip\1.7", true).SetValue("EdgeTargetDockedState", "1", Microsoft.Win32.RegistryValueKind.DWord);
            System.Diagnostics.Process.Start(@"C:\Program Files\Common Files\Microsoft Shared\ink\TabTip.exe");
        }

        /// <summary>
        /// HideSoftKeyboard
        /// </summary>
        private void HideSoftKeyboard()
        {
            int iHandle = FindWindow("IPTIP_Main_Window", "");
            if (iHandle > 0)
            {
            SendMessage(iHandle, WM_SYSCOMMAND, SC_CLOSE, 0);
            }
        }
        }
    }