一个WPF下的虚拟键盘实现

给上位机触摸屏做一个虚拟键盘,这玩意儿不就是一排的网格里面放满button嘛 。说归这样说 依然还是有一堆细节需要你去处理的。不论如何 先画个键盘吧。

 

简单的从网上找个键盘位图做参照使用 4行Grid 布局一下 是不是有模有样。主要是按键的样式要想好看的话的花一些功夫。然后所有的button需要绑定同一个事件,由于WPF里的事件是路由事件 我们直接在最外面的Grid上写 ButtonBase.Click="ButtonGrid_Click" 即可 ,以前竟然没发现还可以这样ButtonBase 了解了。然后有几个蓝色的Fun按键需要做特殊处理和定义, 还有就算我们做成的userControl控件,需要把事件暴露给外部 让按特定键的时候外部写自己的处理逻辑。

按键和事件定义

 1 public Action<object> MyKeyDown;
 2 private String valueString;
 3 
 4 internal String ValueString
 5 {
 6     get { return valueString; }
 7 }
 8 public enum EKeyitem
 9 {
10     DEl,
11     AC,
12     OK,
13     Shift,
14     A
15 }

事件触发

 1 private void ButtonGrid_Click(object sender, RoutedEventArgs e)
 2 {
 3     Button clickedButton = (Button)e.OriginalSource;    //获取click事件触发源,即按了的按钮
 4     if ((String)clickedButton.Content == "DEL")
 5     {
 6         MyKeyDown(EKeyitem.DEl);
 7     }
 8     else if ((String)clickedButton.Content == "AC")
 9     {
10         MyKeyDown(EKeyitem.AC);
11     }
12     else if ((String)clickedButton.Content == "确认")
13     {
14         MyKeyDown(EKeyitem.OK);
15         //this.Close();
16     }
17     else if ((String)clickedButton.Content == "A/a")
18     {
19         for (int j = 1; j < 4; j++)
20         {
21             Grid grd = ButtonGrid.Children[j] as Grid;
22             int count2 = grd.Children.Count;
23             for (int i = 0; i < count2; i++)
24             {
25                 Button buttonTemp = grd.Children[i] as Button;
26                 String contentTemp = buttonTemp.Content as String;
27                 if (contentTemp == "AC" || contentTemp == "A/a")
28                     continue;
29                 buttonTemp.Content = contentTemp[0] > 90 ? contentTemp.ToUpper() : contentTemp.ToLower();
30             }
31         }
32         
33     }
34     else
35     {
36         MyKeyDown((String)clickedButton.Content);
37     }
38 }

 

外部使用,常规usercontrol一样使用,先是引入命名空间xmlns:local="clr-namespace:xxx,由于虚拟键盘有一个特性 ,比如我们点击文本框那么它应该出现,且出现的位置刚好在文本框下方,我点回车虚拟键盘消失,那么这里有一丁丁的奇技淫巧,那就是可以进行绝对定位的canvas组件。

1 <Grid>    
2 <TextBox Width="300" Height="50" FontSize="25" Name="tbx_QueryCode" Text="" PreviewMouseDown="tbx_QueryCode_PreviewMouseDown" KeyDown="tbx_QueryCode_KeyDown" GotFocus="tbx_QueryCode_GotFocus"></TextBox>
3 <Canvas Name="vkContext" Focusable="False" >
4             <local:VKeyBoard Canvas.Left="50" Focusable="False" Canvas.Top="100" Visibility="Hidden"  x:Name="myvk"></local:VKeyBoard>
5         </Canvas>
6     </Grid>

文本框获取焦点时

1 private void tbx_QueryCode_GotFocus(object sender, RoutedEventArgs e)
2 {
3     myvk.Visibility = Visibility.Visible;
4     focusTbx = tbx_QueryCode;
5     RePointKeyBoard();
6 }

虚拟键盘的聚焦

 1 public void RePointKeyBoard()
 2 {
 3     if (focusTbx != null)
 4     {
 5         Point p = focusTbx.TranslatePoint(new Point(0, 0), windContent);
 6                                                                         
 7         this.myvk.SetValue(Canvas.LeftProperty, p.X);
 8         this.myvk.SetValue(Canvas.TopProperty, p.Y + focusTbx.Height);
 9     }
10 
11 }

还有就是虚拟键盘外露给我们事件的处理。

开始时绑定事件

1 private void Window_Loaded(object sender, RoutedEventArgs e)
2 {
3     myvk.MyKeyDown = MyKeyDown;
4 
5 }

外露事件处理

 1 //虚拟键盘事件
 2 private void MyKeyDown(object _key)
 3 {
 4     if (focusTbx == null)
 5     {
 6         myvk.Visibility = Visibility.Hidden;
 7         return;
 8     }
 9     EKeyitem key = EKeyitem.A;
10     if (_key.GetType() == typeof(EKeyitem))
11         key = (EKeyitem)_key;
12 
13     if (key == EKeyitem.DEl)
14     {
15         if (focusTbx.Text.Length > 0)
16         {
17             focusTbx.Text = focusTbx.Text.Substring(0, focusTbx.Text.Length - 1);
18         }
19     }
20     else if (key == EKeyitem.AC)
21     {
22         focusTbx.Text = "";
23     }
24     else if (key == EKeyitem.OK)
25     {
26 
27         myvk.Visibility = Visibility.Hidden;
28         if (vm.LoginOK == true && focusTbx == tbx_QueryCode)
29         {
30             valueString = focusTbx.Text;
31             //this.Close();
32             BarCodeInputKeyDown();
33         }
34     }
35     else if (key == EKeyitem.Shift)
36     {
37 
38     }
39     else
40     {
41         focusTbx.Text += _key.ToString();
42     }
43 }

 

posted @ 2021-04-28 14:53  assassinx  阅读(994)  评论(1编辑  收藏  举报