KeyboardBehavior.cs 7.28 KB
using Microsoft.Xaml.Behaviors;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Windows;
using System.Windows.Controls;

namespace FLY.ControlLibrary.UI.OSK
{
    /// <summary>
    /// 为textbox 添加 虚拟键盘 
    /// </summary>
    public class KeyboardBehavior : Behavior<FrameworkElement>
    {
        /// <summary>
        /// 使能 点击 textbox 弹出虚拟键盘
        /// </summary>
        public static bool Enable = true;
        /// <summary>
        /// 使能 鼠标点击 textbox 弹出虚拟键盘, 只是为了测试!!!!
        /// </summary>
        public static bool EnableMouseDown = false;
        /// <summary>
        /// 虚拟键盘正在显示
        /// </summary>
        public static bool IsKeyboardOnShow = false;

        /// <summary>
        /// 
        /// </summary>
        public KeyboardBehavior()
        {

        }
        /// <summary>
        /// 创建控件时调用
        /// </summary>
        protected override void OnAttached()
        {

            base.OnAttached();

            //DependencyObject dobj = AssociatedObject;//它是Border
            //do
            //{
            //    if (dobj is System.Windows.Controls.TextBox)
            //    {
            //        break;
            //    }
            //    dobj = System.Windows.Media.VisualTreeHelper.GetParent(dobj);
            //} while (dobj != null);

            //TextBox tb = dobj as TextBox;
            TextBox tb = COMMON.GetParent<TextBox>(AssociatedObject);

            if (!tb.AcceptsReturn) //它不能通过按 Enter 键触发换行。 使按Enter 能实现LostFocus
            {
                tb.KeyDown += AssociatedObject_KeyDown;
            }
            //不能在 textbox 添加点击事件, 它根本不触发。。。
            //tb.TouchDown += AssociatedObject_TouchDown;
            //tb.MouseDown += AssociatedObject_MouseDown;


            AssociatedObject.TouchUp += AssociatedObject_TouchDown;
            AssociatedObject.MouseDown += AssociatedObject_MouseDown;
        }

        void AssociatedObject_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (e.Key == System.Windows.Input.Key.Enter)
            {
                TextBox tb = sender as TextBox;
                if (tb.AcceptsReturn)
                    return;
                //触发失去焦点事件!!!!!!!
                //让 绑定的 property 生效

                tb.RaiseEvent(new RoutedEventArgs(TextBox.LostFocusEvent));
            }
        }
        /// <summary>
        /// 销毁控件时调用
        /// </summary>
        protected override void OnDetaching()
        {
            //DependencyObject dobj = AssociatedObject;
            //do
            //{
            //    if (dobj is System.Windows.Controls.TextBox)
            //    {
            //        break;
            //    }
            //    dobj = System.Windows.Media.VisualTreeHelper.GetParent(dobj);
            //} while (dobj != null);

            //TextBox tb = dobj as TextBox;
            TextBox tb = COMMON.GetParent<TextBox>(AssociatedObject);

            tb.KeyDown -= AssociatedObject_KeyDown;

            //border
            AssociatedObject.TouchDown -= AssociatedObject_TouchDown;
            AssociatedObject.MouseDown -= AssociatedObject_MouseDown;

            base.OnDetaching();
        }


        void AssociatedObject_TouchDown(object sender, System.Windows.Input.TouchEventArgs e)
        {
            if (IsKeyboardOnShow)//虚拟键盘已经打开
                return;

            //press release 都会调用
            if (!Enable)
                return;
            DependencyObject dobj = sender as DependencyObject;
            popPad(dobj);

            //不能在 press 时 handle = true。 这样会导致焦点没法落在 textbox 上,而且也没有了 release
            //e.Handled = true;

        }

        void AssociatedObject_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (IsKeyboardOnShow)//虚拟键盘已经打开
                return;

            //press release 都会调用
            if (e.ButtonState == System.Windows.Input.MouseButtonState.Released)
                return;

            if (!Enable)
                return;
            if (!EnableMouseDown)
                return;

            DependencyObject dobj = sender as DependencyObject;
            popPad(dobj);
            //不能在 press 时 handle = true。 这样会导致焦点没法落在 textbox 上,而且也没有了 release
            //e.Handled = true;
        }

        void popPad(DependencyObject dobj)
        {
            TextBox tb = COMMON.GetParent<TextBox>(dobj);

            if (tb != null)
            {
                KeyboardBehavior.PopPad(tb);
            }
        }
        public static void PopPad(TextBox tb)
        {
            IVirtualKeyboard kb;
            string param = "";
            if ((tb.Tag is string))
                param = (string)tb.Tag;
            param = param.ToLower();

            if (param.Contains("full"))
            {
                var fkb = new WdFullKeyboard();
                if (param.Contains("password") || param.Contains("pw"))
                    fkb.IsPwMode = true;

                kb = fkb;

            }
            else
                kb = new WdNumKeyboard();

            Window w = (Window)kb;
            Window window = COMMON.GetWindow(tb);
            w.Owner = window;
            IsKeyboardOnShow = true;
            w.Closed += (s, e) => { 
                
                IsKeyboardOnShow = false;
                if (window == null)
                    return;

                if (window.WindowState == WindowState.Normal) {
                    //当window 为2级时, 关闭虚拟键盘,window有概率不刷新
                    //移动一下界面。 强制令它刷新
                    //window.UpdateLayout() 无效
                    window.Left += 1;
                }
            
            };

            kb.Open(tb);
        }
        public static void PopPad(TextBox tb,Window parentWindow)
        {
            IVirtualKeyboard kb;
            string param = "";
            if ((tb.Tag is string))
                param = (string)tb.Tag;
            param = param.ToLower();

            if (param.Contains("full"))
            {
                var fkb = new WdFullKeyboard();
                if (param.Contains("password") || param.Contains("pw"))
                    fkb.IsPwMode = true;

                kb = fkb;

            }
            else
                kb = new WdNumKeyboard();

            Window w = (Window)kb;
            Window window = parentWindow;
            w.Owner = parentWindow;
            IsKeyboardOnShow = true;
            w.Closed += (s, e) => {

                IsKeyboardOnShow = false;
                if (window == null)
                    return;

                if (window.WindowState == WindowState.Normal)
                {
                    //当window 为2级时, 关闭虚拟键盘,window有概率不刷新
                    //移动一下界面。 强制令它刷新
                    //window.UpdateLayout() 无效
                    window.Left += 1;
                }

            };

            kb.Open(tb);
        }
    }

}