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 按 ...
随机推荐
- hdu1151 Air Raid,DAG图的最小路径覆盖
点击打开链接 有向无环图的最小路径覆盖 = 顶点数- 最大匹配 #include <queue> #include <cstdio> #include <cstring& ...
- C#多线程问题整合
一.跨进程访问组件 错误:线程间操作无效: 从不是创建控件“XXX”的线程访问它 解决方法: 1:把CheckForIllegalCrossThreadCalls设置为false 这个方法只是不去捕获 ...
- hdu 5282 Senior's String 两次dp
题链:http://acm.hdu.edu.cn/showproblem.php?pid=5282 Senior's String Time Limit: 2000/1000 MS (Java/Oth ...
- 怎样将android studio项目导入eclipse
如今,越来越多的开源项目都是用android studio来开发的,所以源码都与eclipse有所不同. 以下是将android studio项目导入eclipse的一般步骤: 1. 先解压项目: 2 ...
- java中的特殊字符集合
JAVA中转义字符: 1.八进制转义序列:\ + 1到3位5数字:范围'\000'~'\377' \0:空字符 2.Unicode转义字符:\u + 四个 十六进制数字:0~65535 ...
- 实现Android ListView 自动加载更多内容
研究了几个小时终于实现了Android ListView 自动加载的效果. 说说我是怎样实现的.分享给大家. 1.给ListView增加一个FooterView,调用addFooterView(foo ...
- sublime text 2安装及使用
1.首先下载Sublime Text:http://www.sublimetext.com/ 2.基本设置.參考此文:http://blog.jobbole.com/40660/ { "au ...
- erlang集群IP及port管理
erlang集群是依靠epmd维护的,epmd是erlang集群节点间port映射的守护进程.负责维护集群内的节点连接.提供节点名称到IP地址及port的解析服务. epmd 自己定义port号 ep ...
- Enhancing the Application: Advanced JDBC Features(转)
Enhancing the Application: Advanced JDBC Features This chapter describes additional functionality th ...
- 自由HTML5串行来到《HTML5具体解释Web开发的例子》连载(三)DOCTYPE和字符集
于2.1.2通过新老科DOCTYPE控制,读者可以清晰地看到HTML 5精简旧体制的努力取得. DOCTYPE主要用于在开始的情况下,XML于,用作叙述性说明XML同意使用的元素.物业和安排.起初HT ...