原文:Windows 8 键盘上推自定义处理

  在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代码如下:

 using System;
using System.Collections.Generic;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.Foundation;
using Windows.UI.Xaml.Media.Animation; namespace HuiZhang212.Keyboard
{
public delegate void InputPaneShowingHandler(object sender, InputPaneVisibilityEventArgs e);
public delegate void InputPaneHidingHandler(InputPane input, InputPaneVisibilityEventArgs e);
public class InputPaneHelper
{
private Dictionary<UIElement, InputPaneShowingHandler> handlerMap;
private UIElement lastFocusedElement = null;
private InputPaneHidingHandler hidingHandlerDelegate = null; public InputPaneHelper()
{
handlerMap = new Dictionary<UIElement, InputPaneShowingHandler>();
} public void SubscribeToKeyboard(bool subscribe)
{
InputPane input = InputPane.GetForCurrentView();
if (subscribe)
{
input.Showing += ShowingHandler;
input.Hiding += HidingHandler;
}
else
{
input.Showing -= ShowingHandler;
input.Hiding -= HidingHandler;
}
} public void AddShowingHandler(UIElement element, InputPaneShowingHandler handler)
{
if (handlerMap.ContainsKey(element))
{
throw new System.Exception("A handler is already registered!");
}
else
{
handlerMap.Add(element, handler);
element.GotFocus += GotFocusHandler;
element.LostFocus += LostFocusHandler;
}
} private void GotFocusHandler(object sender, RoutedEventArgs e)
{
lastFocusedElement = (UIElement)sender;
} private void LostFocusHandler(object sender, RoutedEventArgs e)
{
if (lastFocusedElement == (UIElement)sender)
{
lastFocusedElement = null;
}
} private void ShowingHandler(InputPane sender, InputPaneVisibilityEventArgs e)
{
if (lastFocusedElement != null && handlerMap.Count > )
{
handlerMap[lastFocusedElement](lastFocusedElement, e);
}
lastFocusedElement = null;
} private void HidingHandler(InputPane sender, InputPaneVisibilityEventArgs e)
{
if (hidingHandlerDelegate != null)
{
hidingHandlerDelegate(sender, e);
}
lastFocusedElement = null;
} public void SetHidingHandler(InputPaneHidingHandler handler)
{
this.hidingHandlerDelegate = handler;
} public void RemoveShowingHandler(UIElement element)
{
handlerMap.Remove(element);
element.GotFocus -= GotFocusHandler;
element.LostFocus -= LostFocusHandler;
}
}
}

InputPaneHelper

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

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

 <Page
x:Class="HuiZhang212.Keyboard.KeyboardPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HuiZhang212.Keyboard"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <!--键盘上推和隐藏动画-->
<Page.Resources>
<Storyboard x:Name="MoveMiddleOnShowing">
<DoubleAnimationUsingKeyFrames Duration="0:0:0.733" Storyboard.TargetName="MiddleTranslate" Storyboard.TargetProperty="Y">
<SplineDoubleKeyFrame x:Name="ShowingMoveSpline" KeyTime="0:0:0.733" KeySpline="0.10,0.90, 0.20,1">
</SplineDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard> <Storyboard x:Name="MoveMiddleOnHiding">
<DoubleAnimationUsingKeyFrames Duration="0:0:0.367" Storyboard.TargetName="MiddleTranslate" Storyboard.TargetProperty="Y">
<SplineDoubleKeyFrame KeyTime="0:0:0.367" KeySpline="0.10,0.90, 0.20,1" Value="0">
</SplineDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Page.Resources> <Grid x:Name="LayoutRoot" Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.RenderTransform>
<TranslateTransform x:Name="MiddleTranslate" />
</Grid.RenderTransform>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<FlipView Margin="100">
<FlipViewItem Background="Yellow">
<TextBox Text="自定义监听键盘上推事件" Name="textbox0" Foreground="Black" VerticalAlignment="Bottom" Width="300"/>
</FlipViewItem>
<FlipViewItem Background="Blue">
<TextBox Text="系统处理键盘上推事件" Name="textbox1" Foreground="Black" VerticalAlignment="Bottom" Width="300"/>
</FlipViewItem>
<FlipViewItem Background="Green">
<TextBox Text="自定义监听键盘上推事件" Name="textbox2" Foreground="Black" VerticalAlignment="Top" Width="300"/>
</FlipViewItem>
</FlipView>
</Grid>
</Grid>
</Page>

KeyboardPage.xaml

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

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

 using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation; // “空白页”项模板在 http://go.microsoft.com/fwlink/?LinkId=234238 上有介绍 namespace HuiZhang212.Keyboard
{
/// <summary>
/// 可用于自身或导航至 Frame 内部的空白页。
/// 参考Responding to the appearance of the on-screen keyboard sample
/// FlipView控件中放置的TextBox控件 不会上推
/// </summary>
public sealed partial class KeyboardPage : Page
{
public KeyboardPage()
{
this.InitializeComponent(); AddInputPanelElement(textbox0);
AddInputPanelElement(textbox2);
} protected override void OnNavigatedFrom(NavigationEventArgs e)
{
RemoveInputPanelElement(textbox0);
RemoveInputPanelElement(textbox2);
} #region 键盘上推处理
private double displacement = ;
private InputPaneHelper inputPaneHelper = new InputPaneHelper(); public void AddInputPanelElement(FrameworkElement element)
{
inputPaneHelper.SubscribeToKeyboard(true);
inputPaneHelper.AddShowingHandler(element, new InputPaneShowingHandler(CustomKeyboardHandler));
inputPaneHelper.SetHidingHandler(new InputPaneHidingHandler(InputPaneHiding));
} public void RemoveInputPanelElement(FrameworkElement element)
{
inputPaneHelper.SubscribeToKeyboard(false);
inputPaneHelper.RemoveShowingHandler(element);
inputPaneHelper.SetHidingHandler(null);
} private void CustomKeyboardHandler(object sender, InputPaneVisibilityEventArgs e)
{
// Keep in mind that other elements could be shifting out of your control. The sticky app bar, for example
// will move on its own. You should make sure the input element doesn't get occluded by the bar
FrameworkElement element = sender as FrameworkElement;
Point poppoint = element.TransformToVisual(this).TransformPoint(new Point(, ));
displacement = e.OccludedRect.Y - (poppoint.Y + element.ActualHeight + );
//bottomOfList = MiddleScroller.VerticalOffset + MiddleScroller.ActualHeight; // Be careful with this property. Once it has been set, the framework will
// do nothing to help you keep the focused element in view.
e.EnsuredFocusedElementInView = true; if (displacement > )
{
displacement = ;
} ShowingMoveSpline.Value = displacement;
MoveMiddleOnShowing.Begin();
} private void InputPaneHiding(InputPane sender, InputPaneVisibilityEventArgs e)
{
if (displacement != 0.0)
{
MoveMiddleOnShowing.Stop(); if (displacement < )
{
MoveMiddleOnHiding.Begin();
}
}
}
#endregion
}
}

KeyboardPage.xaml.cs

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

Windows 8 键盘上推自定义处理的更多相关文章

  1. C#中如何截取Windows消息来触发自定义事件

    原文 C#中如何截取Windows消息来触发自定义事件 在c#windows开发中,我们常常会遇到拦截windows消息,来触发某个特定任务的问题. 由于目前使用c#的开发人员非常多,而且大多数c#程 ...

  2. windows phone (12) 小试自定义样式

    原文:windows phone (12) 小试自定义样式 样式在BS开发中经常用到,在wp中系统也提供了解决办法,就是对设置的样式的一种资源共享,首先是共享资源的位置,它是在App类中,之前我们已经 ...

  3. android 透明状态栏方法及其适配键盘上推(二)

    在上一篇文章中介绍了一种设置透明状态栏及其适配键盘上推得方法.但是上一篇介绍的方法中有个缺点,就是不能消除掉statusbar的阴影.很多手机如(三星,Nexus都带有阴影).即使我用了: <a ...

  4. mac与windows共享键盘鼠标(synergy)

    桌面上有两台电脑, 一台mac一台windows, 由于桌面空间紧张, 放两套键盘鼠标有点浪费空间, 如果能让mac和windows共享键盘鼠标就好了, 经过一番搜寻, 找到了一款名为synergy的 ...

  5. windows系统定时重启自定义exe程序

    工作需要, Windows系统定时重启自定义exe程序. 写了如下程序, 按照说明(readme.txt)修改批处理文件中的四个参数即可: 1.readme.txt 第一个参数:进程名(不用带exe) ...

  6. 09 Windows编程——键盘消息

    焦点窗口:接收到这个键盘事件的窗口称为有输入焦点的窗口.具有输入焦点的窗口要么是活动窗口,要么是活动窗口的子孙窗口. 活动窗口:活动窗口通常是很好鉴别的.它总是最上层的窗口——也就是说,它的父窗口句柄 ...

  7. 【转载】修改Windows下键盘按键对应功能的一些方案

    原文见:https://sites.google.com/site/xiangyangsite/home/technical-tips/windows-tips/multi_media_key_cus ...

  8. Linux Windows 修改键盘映射

    Linux 下是编辑 ~/.Xmodmap 文件 remove Lock = Caps_Lockkeysym Escape = Caps_Lockkeysym Caps_Lock = Escapead ...

  9. 【笨嘴拙舌WINDOWS】键盘消息,鼠标消息

    键盘消息 Windows系统无论何时只有一个窗口(可能是子窗口,也就是控件)能获得焦点. 焦点窗口通过windows消息来响应人的键盘操作,与键盘相关的常用消息罗列如下: WM_KEYDOWN   按 ...

随机推荐

  1. hdu 4739【位运算】.cpp

    题意: 给出n个地雷所在位置,正好能够组成正方形的地雷就可以拿走..为了简化题目,只考虑平行于横轴的正方形.. 问最多可以拿走多少个正方形.. 思路: 先找出可以组成正方形的地雷组合cnt个.. 然后 ...

  2. POJ 1018 【枚举+剪枝】.cpp

    题意: 给出n个工厂的产品参数带宽b和价格p,在这n个工厂里分别选1件产品共n件,使B/P最小,其中B表示n件产品中最小的b值,P表示n件产品p值的和. 输入 iCase n 表示iCase个样例n个 ...

  3. 【Energy Big Data】能源互联网和电力大数据

    背景 今年的政府工作报告突出了互联网在经济结构转型中的重要地位,报告明白指出:要制定"互联网+"行动计划,推动移动互联网.云计算.大数据.物联网等与现代制造业结合,促进电子商务.工 ...

  4. 采用CXF+spring+restful创建一个web接口项目

    这篇文章是http://blog.csdn.net/zxnlmj/article/details/28880303下面,加入的基础上的restful特征 1.参加restful必jar包裹 jsr31 ...

  5. C++:抽象基类和纯虚函数的理解

    转载地址:http://blog.csdn.net/acs713/article/details/7352440 抽象类是一种特殊的类,它是为了抽象和设计的目的为建立的,它处于继承层次结构的较上层. ...

  6. GitLal+sourceTree版本号管理

    GitLab+sourceTree版本号管理 假设把代码提交到github上,仅仅能是公开的,除非你花钱了,可是我不想花钱,所以我选择了gitLab作为gitserver,使用gitLab的详细过程例 ...

  7. 【转向Javascript系列】从setTimeout说事件循环模型

    本文首发在alloyteam团队博客,链接地址http://www.alloyteam.com/2015/10/turning-to-javascript-series-from-settimeout ...

  8. error C2471: 无法更新程序数据库

    这段时间在使用VS做一个项目.在使用过程中,今天遇到了一个问题,也就是题目所说的那样: error C2471: 无法更新程序数据库.之后在网上搜了一下,得到了两种解决方案,两种方案分别如下: (一) ...

  9. mv目录前后要加斜杠,否则会当成文件

    mv目录要加斜杠,否则会当成文件

  10. 伪教练技术培训之殇-2013年9月江西IDC拓行榜与综述

    纠集几个人,然后培训所谓的教练技术培训. 培训的人一期又一期的参与,国学.佛学.超能量,无所不用其极,然后就是疯狂的拿人头,邀请朋友加盟. 有甚者还披上“科技”的外衣,用“水知道答案”这种早被公知指出 ...