首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

《Programming WPF》中譯:第 3 章 輸入處理與命令系統

     編輯:關於.NET

WPF 輸入系統建立在路由事件、命令與焦點管理之上,支援滑鼠、鍵盤、觸控筆等多樣輸入裝置。本章詳細說明路由事件機制、三大輸入裝置事件表、命令架構與 CommandBinding 實作。

3.2.1 路由事件

傳統 CLR 事件無處理器時視為無效;WPF 路由事件會沿視覺樹向上(Bubbling)或向下(Tunneling)傳遞,直到根節點。

  • Bubbling:從來源元素向上至根(如 MouseLeftButtonDown)。
  • Tunneling:從根向下至來源,名稱通常加 Preview 前綴(PreviewMouseLeftButtonDown),先於 Bubbling 引發。
  • Direct:僅通知來源元素(如 MouseEnter)。
<Button MouseLeftButtonDown="Handler" PreviewMouseLeftButtonDown="PreviewHandler">
  <Grid ...><Canvas ...><Ellipse .../></Canvas></Grid>
</Button>

按鈕視覺樹 事件路由路徑

點擊 Ellipse 時輸出順序:

PreviewButtonDownButton
PreviewButtonDownGrid
PreviewButtonDownCanvas
PreviewButtonDownEllipse
ButtonDownEllipse
ButtonDownCanvas
ButtonDownGrid
ButtonDownButton

中止路由

在處理器中設定 e.Handled = true 可停止後續傳遞;若在 Preview 階段設定,Bubbling 階段也不會引發。

識別真實來源

sender 為註冊處理器的元素;真實來源在 e.OriginalSource。

CLR 事件包裝

路由事件以標準 CLR 事件包裝暴露,支援 C# += 語法在後台代碼註冊,分離設計師與開發者關注點。

3.2.2 滑鼠輸入

UIElement 定義大量滑鼠路由事件(MouseDown、MouseMove、MouseWheel 等),均為 Tunnel/Bubble 配對。IsMouseOver、IsDirectMouseOver 屬性指示滑鼠是否在元素或其子樹上。

Click 非基本輸入事件:由 ButtonBase 定義,滑鼠/鍵盤均可觸發。透明 Fill 的 Shape 仍可命中測試;若不欲攔截輸入,請完全不設定 Fill(而非透明筆刷)。

3.2.3 鍵盤輸入與焦點

焦點決定鍵盤輸入目標。Focusable 決定元素可否獲焦點(Control 預設 true)。鍵盤事件(KeyDown、KeyUp、TextInput)同為 Tunnel/Bubble 配對。TextInput 為裝置無關文字輸入,手寫輸入亦會引發。

3.2.4 觸控筆輸入

完整事件集:StylusDown/Up、StylusMove、StylusInAirMove、StylusInRange/OutOfRange、StylusSystemGesture、TextInput,均為 Tunnel/Bubble。

3.2.5 命令系統

RoutedCommand 代表可由多種方式(選單、工具列、快捷鍵、腳本)調用的邏輯動作。命令以 Tunnel/Bubble 路由傳遞 PreviewExecute/Execute 事件。

標準命令類別

類別涵蓋命令
ApplicationCommands剪貼簿、復原/重做、文件操作(開啟、列印)
ComponentCommands捲動、移動至末尾、文字選取
EditCommands粗體、斜體、對齊
MediaCommands播放/暫停、音量、軌道選擇

CommandBinding 處理命令

將命令對應至特定元素的處理器,解決單例命令全域觸發問題:

public Window1() {
  InitializeComponent();
  var binding = new CommandBinding(ApplicationCommands.New);
  binding.Executed += NewCommandHandler;
  CommandBindings.Add(binding);
}
void NewCommandHandler(object sender, ExecutedRoutedEventArgs e) {
  if (unsavedChanges) { /* 詢問儲存 */ }
  inputBox.Clear();
}

自訂命令與輸入手勢

public static RoutedCommand FooCommand;
static Window1() {
  var gestures = new InputGestureCollection();
  gestures.Add(new KeyGesture(Key.F, ModifierKeys.Control | ModifierKeys.Shift));
  FooCommand = new RoutedCommand("Foo", typeof(Window1), gestures);
}

XAML 綁定:<Button Command="ApplicationCommands.New" /> 或自訂 <Button Command="local:MyCommands.Foo" />(需 XML Mapping)。

命令啟用狀態

var binding = new CommandBinding(ApplicationCommands.Redo);
binding.CanExecute += (s, e) => e.CanExecute = CanRedo();
CommandBindings.Add(binding);

已知問題:當前版本不會自動將選單/工具列項目灰化,僅阻止執行。

總結

路由事件解決複合控制項輸入分發難題;命令系統統一多入口動作調用;兩者結合構建 WPF 豐富互動基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved