设为首页 收藏本站
查看: 1718|回复: 0

[经验分享] Windows 8 键盘上推自定义处理

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2014-1-17 09:04:12 | 显示全部楼层 |阅读模式
在Windows 8 应用程序中,当TextBox控件获得焦点时,输入面板会弹出,如果TextBox控件处于页面下半部分,则系统会将页面上推是的TextBox不被输入面板盖住,但是当TextBox是在FlipView控件中时,系统不会将页面上推,所以这种情况下输入框被输入面板盖住。具体原因不清楚,不知道是不是系统bug。

  当输入面板弹出,页面上推的操作可以通过监听InputPane的Showing和Hiding事件来处理,既然当TextBox在FlipView控件时,系统没有很好的处理页面上推,那么开发者可以通过监听InputPane的事件来自己处理上推操作。

  Windows 8 的一个实例代码Responding to the appearance of the on-screen keyboard sample中介绍了如果监听处理InputPane的相关操作,参考此实例以FlipView中的TextBox控件为例并对实例代码进行简化处理。

  实例中的InputPaneHelper是对InputPane的事件处理的封装,直接拿来使用,InputPaneHelper代码如下:



1 using System;
2 using System.Collections.Generic;
3 using Windows.UI.ViewManagement;
4 using Windows.UI.Xaml;
5 using Windows.Foundation;
6 using Windows.UI.Xaml.Media.Animation;
7
8 namespace HuiZhang212.Keyboard
9 {
10     public delegate void InputPaneShowingHandler(object sender, InputPaneVisibilityEventArgs e);
11     public delegate void InputPaneHidingHandler(InputPane input, InputPaneVisibilityEventArgs e);
12     public class InputPaneHelper
13     {
14         private Dictionary<UIElement, InputPaneShowingHandler> handlerMap;
15         private UIElement lastFocusedElement = null;
16         private InputPaneHidingHandler hidingHandlerDelegate = null;
17
18         public InputPaneHelper()
19         {
20             handlerMap = new Dictionary<UIElement, InputPaneShowingHandler>();
21         }
22
23         public void SubscribeToKeyboard(bool subscribe)
24         {
25             InputPane input = InputPane.GetForCurrentView();
26             if (subscribe)
27             {
28                 input.Showing += ShowingHandler;
29                 input.Hiding += HidingHandler;
30             }
31             else
32             {
33                 input.Showing -= ShowingHandler;
34                 input.Hiding -= HidingHandler;
35             }
36         }
37
38         public void AddShowingHandler(UIElement element, InputPaneShowingHandler handler)
39         {
40             if (handlerMap.ContainsKey(element))
41             {
42                 throw new System.Exception("A handler is already registered!");
43             }
44             else
45             {
46                 handlerMap.Add(element, handler);
47                 element.GotFocus += GotFocusHandler;
48                 element.LostFocus += LostFocusHandler;
49             }
50         }
51
52         private void GotFocusHandler(object sender, RoutedEventArgs e)
53         {
54             lastFocusedElement = (UIElement)sender;
55         }
56
57         private void LostFocusHandler(object sender, RoutedEventArgs e)
58         {
59             if (lastFocusedElement == (UIElement)sender)
60             {
61                 lastFocusedElement = null;
62             }
63         }
64
65         private void ShowingHandler(InputPane sender, InputPaneVisibilityEventArgs e)
66         {
67             if (lastFocusedElement != null && handlerMap.Count > 0)
68             {
69                 handlerMap[lastFocusedElement](lastFocusedElement, e);
70             }
71             lastFocusedElement = null;
72         }
73
74         private void HidingHandler(InputPane sender, InputPaneVisibilityEventArgs e)
75         {
76             if (hidingHandlerDelegate != null)
77             {
78                 hidingHandlerDelegate(sender, e);
79             }
80             lastFocusedElement = null;
81         }
82
83         public void SetHidingHandler(InputPaneHidingHandler handler)
84         {
85             this.hidingHandlerDelegate = handler;
86         }
87
88         public void RemoveShowingHandler(UIElement element)
89         {
90             handlerMap.Remove(element);
91             element.GotFocus -= GotFocusHandler;
92             element.LostFocus -= LostFocusHandler;
93         }
94     }
95 }

  InputPaneHelper代码比较容易理解,简单的说就是用一个Hash表存储所有需要监听处理键盘上推事件的UIElement(一般情况下应该是TextBox控件),并且通过监听UIElement的焦点事件来判断弹出输入面板是通过那个UIElement触发的,并且通过监听InputPane的Showing和Hiding事件来对键盘上推进行处理。

  测试页面KeyboardPage.xaml代码如下:



1 <Page
2     x:Class="HuiZhang212.Keyboard.KeyboardPage"
3     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5     xmlns:local="using:HuiZhang212.Keyboard"
6     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
7     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8     mc:Ignorable="d">
9
10     <!--键盘上推和隐藏动画-->
11     <Page.Resources>
12         <Storyboard x:Name="MoveMiddleOnShowing">
13             <DoubleAnimationUsingKeyFrames Duration="0:0:0.733" Storyboard.TargetName="MiddleTranslate" Storyboard.TargetProperty="Y">
14                 <SplineDoubleKeyFrame x:Name="ShowingMoveSpline" KeyTime="0:0:0.733" KeySpline="0.10,0.90, 0.20,1">
15                 </SplineDoubleKeyFrame>
16             </DoubleAnimationUsingKeyFrames>
17         </Storyboard>
18
19         <Storyboard x:Name="MoveMiddleOnHiding">
20             <DoubleAnimationUsingKeyFrames Duration="0:0:0.367" Storyboard.TargetName="MiddleTranslate" Storyboard.TargetProperty="Y">
21                 <SplineDoubleKeyFrame KeyTime="0:0:0.367" KeySpline="0.10,0.90, 0.20,1" Value="0">
22                 </SplineDoubleKeyFrame>
23             </DoubleAnimationUsingKeyFrames>
24         </Storyboard>
25     </Page.Resources>
26
27     <Grid x:Name="LayoutRoot" Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
28         <Grid.RenderTransform>
29             <TranslateTransform x:Name="MiddleTranslate" />
30         </Grid.RenderTransform>
31         <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
32             <FlipView Margin="100">
33                 <FlipViewItem Background="Yellow">
34                     <TextBox  Text="自定义监听键盘上推事件" Name="textbox0"  Foreground="Black" VerticalAlignment="Bottom"  Width="300"/>
35                 </FlipViewItem>
36                 <FlipViewItem Background="Blue">
37                     <TextBox  Text="系统处理键盘上推事件" Name="textbox1"  Foreground="Black" VerticalAlignment="Bottom"  Width="300"/>
38                 </FlipViewItem>
39                 <FlipViewItem Background="Green">
40                     <TextBox  Text="自定义监听键盘上推事件" Name="textbox2" Foreground="Black" VerticalAlignment="Top"  Width="300"/>
41                 </FlipViewItem>
42             </FlipView>
43         </Grid>
44     </Grid>
45 </Page>

  MoveMiddleOnShowing和MoveMiddleOnHiding分别是定义的键盘上推和隐藏时的动画,此动画作用在Grid上,当输入面板显示和隐藏时对Grid做此两种动画偏远而达到键盘上推的效果。

  测试代码KeyboardPage.xaml.cs如下:



1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Linq;
5 using Windows.Foundation;
6 using Windows.Foundation.Collections;
7 using Windows.UI.ViewManagement;
8 using Windows.UI.Xaml;
9 using Windows.UI.Xaml.Controls;
10 using Windows.UI.Xaml.Controls.Primitives;
11 using Windows.UI.Xaml.Data;
12 using Windows.UI.Xaml.Input;
13 using Windows.UI.Xaml.Media;
14 using Windows.UI.Xaml.Navigation;
15
16 // “空白页”项模板在 http://go.microsoft.com/fwlink/?LinkId=234238 上有介绍
17
18 namespace HuiZhang212.Keyboard
19 {
20     /// <summary>
21     /// 可用于自身或导航至 Frame 内部的空白页。
22     /// 参考Responding to the appearance of the on-screen keyboard sample
23     /// FlipView控件中放置的TextBox控件 不会上推
24     /// </summary>
25     public sealed partial class KeyboardPage : Page
26     {
27         public KeyboardPage()
28         {
29             this.InitializeComponent();
30
31             AddInputPanelElement(textbox0);
32             AddInputPanelElement(textbox2);
33         }
34
35
36         protected override void OnNavigatedFrom(NavigationEventArgs e)
37         {
38             RemoveInputPanelElement(textbox0);
39             RemoveInputPanelElement(textbox2);
40         }
41
42         #region 键盘上推处理
43         private double displacement = 0;
44         private InputPaneHelper inputPaneHelper = new InputPaneHelper();
45
46         public void AddInputPanelElement(FrameworkElement element)
47         {
48             inputPaneHelper.SubscribeToKeyboard(true);
49             inputPaneHelper.AddShowingHandler(element, new InputPaneShowingHandler(CustomKeyboardHandler));
50             inputPaneHelper.SetHidingHandler(new InputPaneHidingHandler(InputPaneHiding));
51         }
52
53         public void RemoveInputPanelElement(FrameworkElement element)
54         {
55             inputPaneHelper.SubscribeToKeyboard(false);
56             inputPaneHelper.RemoveShowingHandler(element);
57             inputPaneHelper.SetHidingHandler(null);
58         }
59
60         private void CustomKeyboardHandler(object sender, InputPaneVisibilityEventArgs e)
61         {
62             // Keep in mind that other elements could be shifting out of your control. The sticky app bar, for example
63             // will move on its own. You should make sure the input element doesn't get occluded by the bar
64             FrameworkElement element = sender as FrameworkElement;
65             Point poppoint = element.TransformToVisual(this).TransformPoint(new Point(0, 0));
66             displacement = e.OccludedRect.Y - (poppoint.Y + element.ActualHeight + 10);
67             //bottomOfList = MiddleScroller.VerticalOffset + MiddleScroller.ActualHeight;
68
69
70             // Be careful with this property. Once it has been set, the framework will
71             // do nothing to help you keep the focused element in view.
72             e.EnsuredFocusedElementInView = true;
73
74             if (displacement > 0)
75             {
76                 displacement = 0;
77             }
78
79             ShowingMoveSpline.Value = displacement;
80             MoveMiddleOnShowing.Begin();
81         }
82
83         private void InputPaneHiding(InputPane sender, InputPaneVisibilityEventArgs e)
84         {
85             if (displacement != 0.0)
86             {
87                 MoveMiddleOnShowing.Stop();
88
89                 if (displacement < 0)
90                 {
91                     MoveMiddleOnHiding.Begin();
92                 }
93             }
94         }
95         #endregion
96     }
97 }

  测试用例中在FlipView的三个item中分别放置一个TextBox,其中textbox0和textbox2是自定义处理键盘上推事件,而textbox1是由系统处理,通过运行程序可以发现textbox1触发弹出键盘不会使页面上推。而textbox0触发弹出键盘有自定义处理,会使页面上推。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-14348-1-1.html 上篇帖子: windows消息处理(强烈推荐,收藏) 下篇帖子: win8.1 环境下搭建PHP5.5.6+Apache2.4.7 Windows 键盘
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表