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 键盘上推自定义处理的更多相关文章
- C#中如何截取Windows消息来触发自定义事件
原文 C#中如何截取Windows消息来触发自定义事件 在c#windows开发中,我们常常会遇到拦截windows消息,来触发某个特定任务的问题. 由于目前使用c#的开发人员非常多,而且大多数c#程 ...
- windows phone (12) 小试自定义样式
原文:windows phone (12) 小试自定义样式 样式在BS开发中经常用到,在wp中系统也提供了解决办法,就是对设置的样式的一种资源共享,首先是共享资源的位置,它是在App类中,之前我们已经 ...
- android 透明状态栏方法及其适配键盘上推(二)
在上一篇文章中介绍了一种设置透明状态栏及其适配键盘上推得方法.但是上一篇介绍的方法中有个缺点,就是不能消除掉statusbar的阴影.很多手机如(三星,Nexus都带有阴影).即使我用了: <a ...
- mac与windows共享键盘鼠标(synergy)
桌面上有两台电脑, 一台mac一台windows, 由于桌面空间紧张, 放两套键盘鼠标有点浪费空间, 如果能让mac和windows共享键盘鼠标就好了, 经过一番搜寻, 找到了一款名为synergy的 ...
- windows系统定时重启自定义exe程序
工作需要, Windows系统定时重启自定义exe程序. 写了如下程序, 按照说明(readme.txt)修改批处理文件中的四个参数即可: 1.readme.txt 第一个参数:进程名(不用带exe) ...
- 09 Windows编程——键盘消息
焦点窗口:接收到这个键盘事件的窗口称为有输入焦点的窗口.具有输入焦点的窗口要么是活动窗口,要么是活动窗口的子孙窗口. 活动窗口:活动窗口通常是很好鉴别的.它总是最上层的窗口——也就是说,它的父窗口句柄 ...
- 【转载】修改Windows下键盘按键对应功能的一些方案
原文见:https://sites.google.com/site/xiangyangsite/home/technical-tips/windows-tips/multi_media_key_cus ...
- Linux Windows 修改键盘映射
Linux 下是编辑 ~/.Xmodmap 文件 remove Lock = Caps_Lockkeysym Escape = Caps_Lockkeysym Caps_Lock = Escapead ...
- 【笨嘴拙舌WINDOWS】键盘消息,鼠标消息
键盘消息 Windows系统无论何时只有一个窗口(可能是子窗口,也就是控件)能获得焦点. 焦点窗口通过windows消息来响应人的键盘操作,与键盘相关的常用消息罗列如下: WM_KEYDOWN 按 ...
随机推荐
- AC自动机---个人总结
比较好的 AC自动机算法详解.. [转]http://www.cppblog.com/mythit/archive/2009/04/21/80633.html 个人总结:[图是盗用的..] ac自动机 ...
- Spark技术内幕:Stage划分及提交源代码分析
当触发一个RDD的action后.以count为例,调用关系例如以下: org.apache.spark.rdd.RDD#count org.apache.spark.SparkContext#run ...
- VS2010添加默认路径,库以及Lib
下面以OpenCV为例,不需要每次打开VS2010都手动添加OpenCV的库和lib,具体方法如下: VC++目录 步骤一:用任意文本编辑器打开: VS安装目录中的\VC\VCWizards\def ...
- sql语句中 limi的用法
SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset 使用查询语句时需要返回前几条或者中间的某几行数据时可以用到limit 例如 ...
- Top 10 Mistakes Java Developers Make(转)
文章列出了Java开发者最常犯的是个错误. 1.将数组转换为ArrayList 为了将数组转换为ArrayList,开发者经常会这样做: ? 1 List<String> list = A ...
- wamp在win7下64位系统memcache/memcached安装教程
折腾了1个多小时,终于搞定.操作系统时64位的,php5.3.13 类似于上一篇的xdebug安装教程~~ memcache和memcached的区别 在自己的新程序中打算全面应用memcached ...
- 【甘道夫】Apache Hadoop 2.5.0-cdh5.2.0 HDFS Quotas 配额控制
前言 HDFS为管理员提供了针对文件夹的配额控制特性,能够控制名称配额(指定文件夹下的文件&文件夹总数),或者空间配额(占用磁盘空间的上限). 本文探究了HDFS的配额控制特性,记录了各类配额 ...
- 从零开始学Xamarin.Forms(一) 概述
原文:从零开始学Xamarin.Forms(一) 概述 Xamarin 读 "ˈzæmərin",是一个基于开源项目mono的能够使用C#开发的收费的跨平台(iOS.And ...
- 使用JavaMail发送和接收电子邮件
一. 为什么要学习JavaMail 为什么要学习JavaMail开发? 如今非常多WEB应用在开发时都须要集成邮件发送功能.比如: 1. 给新注冊的用户自己主动发送一封包括其注冊信息的欢迎E-Mail ...
- EXCEL随机密码生成函数
=CHAR(INT(RAND()*+))&INT(RAND()*+)&CHAR(INT(RAND()*+))&INT(RAND()*+)&CHAR(INT(RAND() ...