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
}
}