using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; namespace Muchinfo.WPF.Controls.Keyboard { public class PassWordKeyBoard : Window { #region fields private static Control _currentControl; private const double HeightTouchKeyboard = 190; private static Window _instanceObject; private static Brush _previousTextBoxBackgroundBrush = null; private static Brush _previousTextBoxBorderBrush = null; private static Thickness _previousTextBoxBorderThickness; private static double _widthTouchKeyboard = 400; #endregion #region DependencyProperty /// /// 特殊数字字符 /// public ObservableCollection SpecialNumberChars { get { return (ObservableCollection)GetValue(SpecialNumberCharsProperty); } set { SetValue(SpecialNumberCharsProperty, value); } } // Using a DependencyProperty as the backing store for SpecialChars. This enables animation, styling, binding, etc... public static readonly DependencyProperty SpecialNumberCharsProperty = DependencyProperty.Register("SpecialNumberChars", typeof(ObservableCollection), typeof(PassWordKeyBoard), new PropertyMetadata(new ObservableCollection())); /// /// 英文字母 /// public ObservableCollection EnglishChars { get { return (ObservableCollection)GetValue(EnglishCharsProperty); } set { SetValue(EnglishCharsProperty, value); } } // Using a DependencyProperty as the backing store for EnglishChars. This enables animation, styling, binding, etc... public static readonly DependencyProperty EnglishCharsProperty = DependencyProperty.Register("EnglishChars", typeof(ObservableCollection), typeof(PassWordKeyBoard), new PropertyMetadata(new ObservableCollection())); /// /// 用户按下回车 /// public ICommand EnterCommand { get { return (ICommand)GetValue(EnterCommandProperty); } set { SetValue(EnterCommandProperty, value); } } // Using a DependencyProperty as the backing store for EnterCommand. This enables animation, styling, binding, etc... public static readonly DependencyProperty EnterCommandProperty = DependencyProperty.Register("EnterCommand", typeof(ICommand), typeof(PassWordKeyBoard), new PropertyMetadata(null)); /// /// 用户按下空格 /// public ICommand SpaceCommand { get { return (ICommand)GetValue(SpaceCommandProperty); } set { SetValue(SpaceCommandProperty, value); } } // Using a DependencyProperty as the backing store for SpaceCommand. This enables animation, styling, binding, etc... public static readonly DependencyProperty SpaceCommandProperty = DependencyProperty.Register("SpaceCommand", typeof(ICommand), typeof(PassWordKeyBoard), new PropertyMetadata(null)); /// /// 用户按下退格键 /// public ICommand BackSpaceCommand { get { return (ICommand)GetValue(BackSpaceCommandProperty); } set { SetValue(BackSpaceCommandProperty, value); } } // Using a DependencyProperty as the backing store for BackSpaceCommand. This enables animation, styling, binding, etc... public static readonly DependencyProperty BackSpaceCommandProperty = DependencyProperty.Register("BackSpaceCommand", typeof(ICommand), typeof(PassWordKeyBoard), new PropertyMetadata(null)); /// /// 用户按下清除键 /// public ICommand ClearCommand { get { return (ICommand)GetValue(ClearCommandProperty); } set { SetValue(ClearCommandProperty, value); } } // Using a DependencyProperty as the backing store for ClearCommand. This enables animation, styling, binding, etc... public static readonly DependencyProperty ClearCommandProperty = DependencyProperty.Register("ClearCommand", typeof(ICommand), typeof(PassWordKeyBoard), new PropertyMetadata(null)); #endregion public PassWordKeyBoard() { InitCharCommand(); SetCommandBinding(); this.Height = HeightTouchKeyboard; this.Width = _widthTouchKeyboard; } static PassWordKeyBoard() { DefaultStyleKeyProperty.OverrideMetadata(typeof(PassWordKeyBoard), new FrameworkPropertyMetadata(typeof(PassWordKeyBoard))); } #region Properties public static string TouchScreenText { get { if (_currentControl is TextBox) { return ((TextBox)_currentControl).Text; } else if (_currentControl is PasswordBox) { return ((PasswordBox)_currentControl).Password; } else return ""; } set { if (_currentControl is TextBox) { ((TextBox)_currentControl).Text = value; } else if (_currentControl is PasswordBox) { ((PasswordBox)_currentControl).Password = value; } } } public static double WidthTouchKeyboard { get { return _widthTouchKeyboard; } set { _widthTouchKeyboard = value; } } #endregion Properties #region Methods /// /// 初始化字符列表 /// private void InitCharCommand() { //32为空格,密码不使用空格 List keyModelList = new List(); for (byte ch = 33; ch < 127; ch++) { keyModelList.Add(new KeyModel() { KeyChar = Convert.ToChar(ch), CharValue = ch, KeyRoutedCommand = new RoutedCommand() }); } List numberChars = new List (keyModelList.Where(ch => ch.CharValue >= 48 && ch.CharValue <= 57)); var englishChars = new List (keyModelList.Where(ch => ch.CharValue >= 65 && ch.CharValue <= 90)); //取 englishChars = RandomList(englishChars);// 打乱排序 EnglishChars = new ObservableCollection(englishChars); if (numberChars.Any() && EnglishChars.Any()) { List specialChars = new List(keyModelList.Where(ch => !numberChars.Contains(ch) && !EnglishChars.Contains(ch) && (ch.CharValue < 97 || ch.CharValue > 122) )); numberChars = RandomList(numberChars);// 打乱排序 specialChars = RandomList(specialChars); specialChars.AddRange(numberChars); SpecialNumberChars = new ObservableCollection(specialChars); } } //点按钮执行的命令 private void RunCommand(object sender, ExecutedRoutedEventArgs e) { if (e.Parameter == null) return; PassWordKeyBoard.TouchScreenText += e.Parameter.ToString(); } /// /// 注册字符命令 /// private void SetCommandBinding() { //注册特殊字符\数字命令 foreach (KeyModel keyModel in SpecialNumberChars) { var commandBinding = new CommandBinding(keyModel.KeyRoutedCommand, RunCommand); CommandManager.RegisterClassCommandBinding(typeof(PassWordKeyBoard), commandBinding); } //注册字母命令 foreach (KeyModel englishChar in EnglishChars) { var englishBinding = new CommandBinding(englishChar.KeyRoutedCommand, RunCommand); CommandManager.RegisterClassCommandBinding(typeof(PassWordKeyBoard), englishBinding); } //回车 EnterCommand = new RoutedCommand(); var enterBinding = new CommandBinding(EnterCommand, ControlRunCommand); CommandManager.RegisterClassCommandBinding(typeof(PassWordKeyBoard), enterBinding); //空格 SpaceCommand = new RoutedCommand(); var spaceBinding = new CommandBinding(SpaceCommand, ControlRunCommand); CommandManager.RegisterClassCommandBinding(typeof(PassWordKeyBoard), spaceBinding); //退格 BackSpaceCommand = new RoutedCommand(); var backSpacBinding = new CommandBinding(BackSpaceCommand, ControlRunCommand); CommandManager.RegisterClassCommandBinding(typeof(PassWordKeyBoard), backSpacBinding); //清除 ClearCommand = new RoutedCommand(); var clearBinding = new CommandBinding(ClearCommand, ControlRunCommand); CommandManager.RegisterClassCommandBinding(typeof(PassWordKeyBoard), clearBinding); } //执行控制命令 private void ControlRunCommand(object sender, ExecutedRoutedEventArgs e) { if (e.Command == EnterCommand) { if (_instanceObject != null) { _instanceObject.Close(); _instanceObject = null; } _currentControl.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next)); } else if (e.Command == SpaceCommand) { PassWordKeyBoard.TouchScreenText += " "; } else if (e.Command == BackSpaceCommand) { if (!string.IsNullOrEmpty(PassWordKeyBoard.TouchScreenText)) { PassWordKeyBoard.TouchScreenText = PassWordKeyBoard.TouchScreenText.Substring(0, PassWordKeyBoard.TouchScreenText.Length - 1); } } else if (e.Command == ClearCommand) { PassWordKeyBoard.TouchScreenText = ""; } } public static void Dispose() { _currentControl = null; _previousTextBoxBackgroundBrush = null; _previousTextBoxBorderBrush = null; if (_instanceObject != null) { _instanceObject.Close(); _instanceObject = null; } } public static readonly DependencyProperty TouchScreenKeyboardProperty = DependencyProperty.RegisterAttached("TouchScreenKeyboard", typeof(bool), typeof(PassWordKeyBoard), new UIPropertyMetadata(default(bool), TouchScreenKeyboardPropertyChanged)); public static bool GetTouchScreenKeyboard(DependencyObject obj) { return (bool)obj.GetValue(TouchScreenKeyboardProperty); } public static void SetTouchScreenKeyboard(DependencyObject obj, bool value) { obj.SetValue(TouchScreenKeyboardProperty, value); } static void OnGotFocus(object sender, RoutedEventArgs e) { var host = sender as Control; if (host != null) { _previousTextBoxBackgroundBrush = host.Background; _previousTextBoxBorderBrush = host.BorderBrush; _previousTextBoxBorderThickness = host.BorderThickness; //host.Background = Brushes.Yellow; //host.BorderBrush = Brushes.Red; host.BorderThickness = new Thickness(host.BorderThickness.Bottom+1); host.BorderThickness = new Thickness(2); _currentControl = host; if (_instanceObject == null) { FrameworkElement ct = host; while (true) { if (ct is Window) { ((Window)ct).Activated += new EventHandler(TouchScreenKeyboard_Activated); ((Window)ct).Deactivated += new EventHandler(TouchScreenKeyboard_Deactivated); break; } ct = (FrameworkElement)ct.Parent; } _instanceObject = new PassWordKeyBoard(); _instanceObject.AllowsTransparency = true; _instanceObject.WindowStyle = WindowStyle.None; _instanceObject.ShowInTaskbar = false; _instanceObject.ShowInTaskbar = false; _instanceObject.Topmost = true; SyncChild(); // host.LayoutUpdated += new EventHandler(tb_LayoutUpdated); } } } static void OnLostFocus(object sender, RoutedEventArgs e) { Control host = sender as Control; host.Background = _previousTextBoxBackgroundBrush; host.BorderBrush = _previousTextBoxBorderBrush; host.BorderThickness = _previousTextBoxBorderThickness; if (_instanceObject != null) { _instanceObject.Close(); _instanceObject = null; } SetTouchScreenKeyboard(host, false); //设置只有使用按键时才打开键盘。 host.GotFocus -= OnGotFocus; host.LostFocus -= OnLostFocus; } private static void OnUnloaded(object sender, RoutedEventArgs e) { if (_instanceObject != null) { _instanceObject.Close(); } } /// /// Syncs the child. /// private static void SyncChild() { if (_currentControl != null && _instanceObject != null) { Point virtualpoint = new Point(0, _currentControl.ActualHeight + 3); Point Actualpoint = _currentControl.PointToScreen(virtualpoint); if (WidthTouchKeyboard + Actualpoint.X > SystemParameters.VirtualScreenWidth) { double difference = WidthTouchKeyboard + Actualpoint.X - SystemParameters.VirtualScreenWidth; _instanceObject.Left = Actualpoint.X - difference; } else if (!(Actualpoint.X > 1)) { _instanceObject.Left = 1; } else { _instanceObject.Left = Actualpoint.X; } _instanceObject.Top = Actualpoint.Y; _instanceObject.Show(); } } static void TouchScreenKeyboardPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { FrameworkElement host = sender as FrameworkElement; if (host != null && e.NewValue.Equals(true)) { host.GotFocus += new RoutedEventHandler(OnGotFocus); host.Unloaded += OnUnloaded; host.LostFocus += new RoutedEventHandler(OnLostFocus); } } static void TouchScreenKeyboard_Activated(object sender, EventArgs e) { if (_instanceObject != null) { _instanceObject.Topmost = true; } } static void TouchScreenKeyboard_Deactivated(object sender, EventArgs e) { if (_instanceObject != null) { _instanceObject.Topmost = false; } } /// /// 随机打乱一组数据。 /// /// 泛型T /// T列表 /// private List RandomList(List Tlist) { if (Tlist == null || Tlist.Count == 0) return null; Random random = new Random(); ; T Temp; for (int i = Tlist.Count - 1; i > 0; i--) { int j = random.Next(i); Temp = Tlist[i]; Tlist[i] = Tlist[j]; Tlist[j] = Temp; } return Tlist; } #endregion Methods } }