在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 > 0)
{
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代碼比較容易理解,簡單的說就是用一個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&q
uot;
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>
查看本欄目