using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Interactivity; using System.Windows; using System.Windows.Controls; namespace FLY.UI.OSK { /// /// 为textbox 添加 虚拟键盘 /// public class KeyboardBehavior : Behavior { /// /// 使能 点击 textbox 弹出虚拟键盘 /// public static bool Enable = true; /// /// 使能 鼠标点击 textbox 弹出虚拟键盘, 只是为了测试!!!! /// public static bool EnableMouseDown = false; /// /// 虚拟键盘正在显示 /// public static bool IsKeyboardOnShow = false; public KeyboardBehavior() { } /// /// 创建控件时调用 /// 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; 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)); } } /// /// 销毁控件时调用 /// 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; 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) { //向上查找,直到是System.Windows.Controls.TextBox do { if (dobj is System.Windows.Controls.TextBox) { break; } dobj = System.Windows.Media.VisualTreeHelper.GetParent(dobj); } while (dobj != null); DependencyObject dobj_window = dobj; //一直向上找,直到找到window do { if (dobj_window is Window) { break; } dobj_window = System.Windows.Media.VisualTreeHelper.GetParent(dobj_window); } while (dobj_window != null); if (dobj != null) { System.Windows.Controls.TextBox tb = dobj as System.Windows.Controls.TextBox; IVirtualKeyboard kb; if ((tb.Tag is string) && ((string)tb.Tag == "Full")) kb = new Window_FullPad(); else kb = new Window_NumPad(); Window w = (Window)kb; w.Owner = dobj_window as Window; IsKeyboardOnShow = true; w.Closed += (s, e) => { IsKeyboardOnShow = false; }; kb.Open(tb); } } } }