原文: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 4869 Turn the pokers(推理)

    HDU 4869 Turn the pokers 题目链接 题意:给定n个翻转扑克方式,每次方式相应能够选择当中xi张进行翻转.一共同拥有m张牌.问最后翻转之后的情况数 思路:对于每一些翻转,假设能确 ...

  2. SVN的log,cat,list,diff的使用

     svn log          展示给你主要信息:每个版本附加在版本上的作者与日期信息和所有路径修改. svn diff          显示特定修改的行级详细信息. svn cat       ...

  3. mybatis配置文件xxxx.xml中缺失返回类型的后果A query was run and no Result Maps were found

    使用mybatis时出现异常问题: 有如下的错误 Error querying database.  Cause: org.apache.ibatis.executor.ExecutorExcepti ...

  4. JavaScript的作用域和变量对象

    变量对象 先来说说什么是变量对象.变量对象中又存储了什么东西吧. JavaScript中的运行环境包含全局运行环境和函数运行环境这两种,每进入到一个运行环境都会创建一个变量对象,这个对象中记录了在当前 ...

  5. 简单工厂 VS 工厂方法 VS 抽象工厂

    说到设计模式.自然少不了简单工厂模式.工厂方法和抽象工厂这三姐妹. 它们之间可谓是各有所长,术业专攻啊!这篇博客来简单的梳理一下三者之间的关系. 那么工厂又是什么意思呢?结合三者的特点,我觉得能够这样 ...

  6. (step7.2.1)hdu 1395(2^x mod n = 1——简单数论)

    题目大意:输入一个整数n,输出使2^x mod n = 1成立的最小值K 解题思路:简单数论 1)n可能不能为偶数.因为偶数可不可能模上偶数以后==1. 2)n肯定不可能为1 .因为任何数模上1 == ...

  7. 高性能 TCP &amp; UDP 通信框架 HP-Socket v3.2.2 正式公布

    HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包括服务端组件.client组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#. ...

  8. JSP生成word文件

    1.jsp生成word文件,直接改动jsp格式: <%@ page contentType="application/vnd.ms-word;charset=GB2312"% ...

  9. 王立平--include在Android应用

    它包括一个布局和布局 1.在layout确定activity_other.xml布局 2.代码中的包括例如以下: <LinearLayout xmlns:android="http:/ ...

  10. mybatis与mysql插入时返回主键id的值

    <insert id="insertCharge" parameterType="com.bb.bean.Rechargerecord"> < ...