Windows 8 輸入模型統一了滑鼠、觸控、筆、鍵盤。本文涵蓋:硬體能力偵測、軟鍵盤 (SIP) 控制、Tab 導航屬性、Pointer 事件全家桶、Tap 系列事件、Drag/Drop 基礎,為觸控應用打下堅實基礎。
// 滑鼠
var mouse = new MouseCapabilities();
Log($"MousePresent: {mouse.MousePresent}"); // 1/0
Log($"Buttons: {mouse.NumberOfButtons}");
Log($"HorizontalWheel: {mouse.HorizontalWheelPresent}");
Log($"VerticalWheel: {mouse.VerticalWheelPresent}");
Log($"SwapButtons: {mouse.SwapButtons}");
// 鍵盤
var kb = new KeyboardCapabilities();
Log($"KeyboardPresent: {kb.KeyboardPresent}"); // 1/0
// 觸控
var touch = new TouchCapabilities();
Log($"TouchPresent: {touch.TouchPresent}"); // 1/0
Log($"Contacts: {touch.Contacts}"); // 多點觸控點數
// 統一 Pointer 設備列舉
foreach (var dev in PointerDevice.GetPointerDevices())
{
Log($"Type: {dev.PointerDeviceType}"); // Touch/Pen/Mouse
Log($"Integrated: {dev.IsIntegrated}");
Log($"MaxContacts: {dev.MaxContacts}");
Log($"PhysicalRect: {dev.PhysicalDeviceRect}");
Log($"ScreenRect: {dev.ScreenRect}");
}
TextBox/RichEditBox/PasswordBox 獲得焦點 → 自動顯示。IsReadOnly="True" 即使焦點也不顯示。
<TextBox InputScope="Default" />
<TextBox>
<TextBox.InputScope>
<InputScope><InputScopeName NameValue="TelephoneNumber" /></InputScope>
</TextBox.InputScope>
</TextBox>
支援 InputScopeNameValue 列舉:Text, Number, TelephoneNumber, EmailSmtpAddress, Url, Search, Formula, Date, Time, ...。
var state = Window.Current.CoreWindow.GetKeyState(VirtualKey.CapitalLock);
if (state == CoreVirtualKeyStates.Locked) await new MessageDialog("大寫鎖定開啟").ShowAsync();
// Enter 鍵隱藏鍵盤
void TextBox_KeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key == VirtualKey.Enter)
txtReadOnly.Focus(FocusState.Programmatic); // 移走焦點
}
var pane = InputPane.GetForCurrentView();
pane.Showing += (s,e) => { var rect = e.OccludedRect; /* 調整 UI 避開鍵盤 */ };
pane.Hiding += (s,e) => { /* 還原 UI */ };
<Button Content="Button 1" TabIndex="3" />
<Button Content="Button 2" TabIndex="1" />
<Button Content="Button 3" IsTabStop="False" /> <!-- 排除 Tab 順序 -->
<Button Content="Button 4" TabIndex="4" />
<Button Content="Button 5" TabIndex="2" />
TabNavigation 屬性在 WinRT 中實測效果有限,主要靠 TabIndex + IsTabStop 控制。
| 事件 | 觸發時機 |
|---|---|
| PointerEntered / PointerExited | 指進入/離開元素範圍 |
| PointerPressed / PointerReleased | 按下/釋放 (含滑鼠、觸控、筆) |
| PointerMoved | 移動中 (高頻) |
| PointerWheelChanged | 滑鼠滾輪 |
| PointerCanceled / PointerCaptureLost | 輸入取消/捕獲遺失 |
| Holding | 長按 (觸控/筆) |
var props = e.GetCurrentPoint(null).Properties;
Log($"ContactRect: {props.ContactRect}"); // 接觸區域矩形
Log($"Pressure: {props.Pressure}"); // 0.0-1.0 壓力
Log($"IsLeftButtonPressed: {props.IsLeftButtonPressed}");
Log($"IsRightButtonPressed: {props.IsRightButtonPressed}");
Log($"IsPrimary: {props.IsPrimary}"); // 主要指針 (第一根手指/滑鼠)
Log($"PointerUpdateKind: {props.PointerUpdateKind}"); // 變更類型枚舉
void Rect_PointerPressed(object sender, PointerRoutedEventArgs e)
{
((UIElement)sender).CapturePointer(e.Pointer); // 捕獲
}
void Rect_PointerReleased(object sender, PointerRoutedEventArgs e)
{
((UIElement)sender).ReleasePointerCapture(e.Pointer); // 釋放
}
Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Cross, 1);
| 事件 | 觸發條件 | 事件參數關鍵屬性 |
|---|---|---|
| Tapped | 單擊/單指輕觸 | PointerDeviceType, GetPosition() |
| DoubleTapped | 雙擊/雙指快速輕觸 | 同上 |
| RightTapped | 右鍵/長按 (觸控) | 同上 |
| Holding | 長按持續 | HoldingState (Started/Completed/Canceled) |
rectangle.IsTapEnabled = true; // 預設 true
rectangle.IsDoubleTapEnabled = true;
rectangle.IsRightTapEnabled = true;
rectangle.IsHoldingEnabled = true;
WinRT AllowDrop, Drop, DragEnter, DragOver, DragLeave 事件模式與 WPF 類似,詳細實作請參考 Controls/GridView/DragItem.xaml 範例。
InputScope。InputPane.Showing/Hiding 避免鍵盤遮擋關鍵 UI。Pointer 統一事件模型,CapturePointer 實現拖曳。IsTapEnabled/IsHoldingEnabled 等屬性。GridView 內建 DragItemsStarting 等高階 API。