Windows 8 專為觸控設計,裝置普遍支援多點觸控。開發者需掌握:**手勢識別 API (Manipulation/Tap/Hold)** 與 **Pointer 統一輸入模型 (滑鼠/觸控/筆合一)**,打造自然、流暢、高效能的互動體驗。
| 手勢 | 動作描述 | 典型場景 |
|---|---|---|
| Tap (點擊) | 單指觸碰→抬起 | 按鈕觸發、項目選取、導航 |
| Double Tap (雙擊) | 快速兩次點擊 | 縮放切換、編輯模式進入 |
| Hold (長按/按住) | 單指觸碰保持 ~1秒 | 顯示內容選單 (複製/刪除/更多)、ToolTip |
| Slide/Slide (滑動/拖曳) | 單/多指同方向移動 | 捲動清單、拖曳排序、Canvas 繪圖 |
| Swipe (輕掃) | 短距離快速移動 | 翻頁、刪除項目 (邊緣輕掃)、AppBar 呼出 |
| Pinch (捏合/縮放) | 雙指靠攏/分開 | 圖片/地圖/文件縮放 |
| Rotate (旋轉) | 雙指繞中心弧線移動 | 圖片旋轉、3D 模型視角 |
所有連續手勢 (滑動、縮放、旋轉、慣性) 均透過 `UIElement` 的 `Manipulation` 事件家族處理:
獨立於 Manipulation,針對單點觸控語意:
// XAML
// Code-behind
void Img_Tapped(object sender, TappedRoutedEventArgs e) { /* 單擊導航 */ }
void Img_Holding(object sender, HoldingRoutedEventArgs e) {
if (e.HoldingState == HoldingState.Started) ShowContextMenu(e.GetPosition(sender as UIElement));
}
void Img_RightTapped(object sender, RightTappedRoutedEventArgs e) { /* 滑鼠右鍵/長按同義 */ }


private CompositeTransform _transform = new CompositeTransform();
private void Target_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) {
// 1. 累加平移
_transform.TranslateX += e.Delta.Translation.X;
_transform.TranslateY += e.Delta.Translation.Y;
// 2. 累加縮放 (以操控中心為基準)
_transform.ScaleX *= e.Delta.Scale;
_transform.ScaleY *= e.Delta.Scale;
// 若需固定中心點縮放,需配合 CenterPoint/RenderTransformOrigin 計算位移補償
// 3. 累加旋轉 (弧度轉角度)
_transform.Rotation += e.Delta.Rotation * 180 / Math.PI;
// 4. 套用至目標元素
targetElement.RenderTransform = _transform;
}



傳統開發需分別處理 `MouseLeftButtonDown`、`TouchDown`、`StylusDown`,程式碼重複、易錯。WinRT 引入 **Pointer** 抽象層:所有輸入裝置產生 `PointerPoint`,統一透過 `PointerPressed`、`PointerMoved`、`PointerReleased`、`PointerExited`、`PointerEntered`、`PointerWheelChanged` 事件傳遞。
// XAML:
private List _currentStroke = new List();
private Polyline _currentPolyline;
void OnPressed(object sender, PointerRoutedEventArgs e) {
var pt = e.GetCurrentPoint(inkCanvas).Position;
_currentStroke.Clear();
_currentStroke.Add(pt);
_currentPolyline = new Polyline { Stroke = new SolidColorBrush(Colors.Black), StrokeThickness = 2 };
inkCanvas.Children.Add(_currentPolyline);
inkCanvas.CapturePointer(e.Pointer); // 關鍵:捕捉指標,即使移出 Canvas 仍收到事件
}
void OnMoved(object sender, PointerRoutedEventArgs e) {
var pt = e.GetCurrentPoint(inkCanvas).Position;
_currentStroke.Add(pt);
_currentPolyline.Points = new PointCollection(_currentStroke); // 即時重繪
// 進階:使用 e.GetIntermediatePoints(inkCanvas) 取得高頻點平滑曲線
}
void OnReleased(object sender, PointerRoutedEventArgs e) {
inkCanvas.ReleasePointerCapture(e.Pointer);
_currentPolyline = null; // 筆劃完成
}
void OnExited(object sender, PointerRoutedEventArgs e) => OnReleased(sender, e); // 視同釋放



