Language: HTML | XAML

回應鍵盤互動 (XAML)

Applies to Windows and Windows Phone

同時使用鍵盤與類別事件處理常式,從硬體或應用程式中的觸控式鍵盤回應按鍵輸入動作。

重要  

有些 Windows 執行階段控制項可在內部處理輸入事件。在這種情況下,因為事件接聽程式不會叫用相關處理常式,所以看起來像是沒有發生輸入事件。這個按鍵子集通常是由類別處理常式處理,為基本鍵盤協助工具提供內建支援。例如,Button 類別會覆寫空格鍵與 Enter 鍵的 OnKeyDown 事件 (以及 OnPointerPressed),並將這些事件路由傳送到控制項的 Click 事件。如果按下按鍵是由控制項類別處理,就不會引發 KeyDownKeyUp 事件。

這樣會提供等同叫用按鈕的內建鍵盤,類似使用手指點選或使用滑鼠按一下。不是空格鍵或 Enter 鍵的按鍵仍會引發 KeyDownKeyUp 事件。如需類別型事件處理運作方式 (尤其是控制項中的輸入事件處理常式) 的詳細資訊,請參閱事件與路由事件概觀。

提示  這個主題的資訊是專門用來開發使用 C++、C# 或 Visual Basic 的應用程式。

對於使用 JavaScript 的應用程式,請參閱回應鍵盤互動 (HTML)

先決條件:  請仔細閱讀這些主題以熟悉這裡討論的技術。

使用 C# 或 Visual Basic 建立您的第一個 Windows 市集應用程式

使用 C++ 建立您的第一個 Windows 市集應用程式

使用 C# 或 Visual Basic 建立 Windows 市集應用程式的藍圖

使用 C++ 建立 Windows 市集應用程式的藍圖

請參閱事件與路由事件概觀以了解事件

應用程式功能,從開始到完成:  應用程式功能,從開始到完成系列深入探索此功能。

使用者互動,從開始到完成 (XAML)

使用者互動自訂,從開始到完成 (XAML)

使用者經驗指導方針:  

平台控制項程式庫 (HTMLXAML) 提供完整的使用者互動體驗,包含標準互動、動畫物理效果及視覺化回饋。 如果您不需要自訂的互動支援,請使用這些內建控制項。

如果平台控制項不足,下列使用者互動指導方針能讓您在各種輸入模式下提供令人讚賞的沈浸式互動體驗。這些指導方針主要著重在觸控輸入,不過與觸控板、滑鼠、鍵盤和手寫筆輸入仍有相關。

範例:  應用程式範例中,查看此功能的執行方式。

輸入範例

輸入:裝置功能範例

輸入:觸控式鍵盤範例

回應螢幕小鍵盤外觀的範例。

概觀

鍵盤輸入是應用程式之整體使用者互動經驗的一個重要部分。對於某些行動不便的人或認為使用鍵盤與應用程式互動較有效率的使用者來說,鍵盤是不可或缺的。例如,使用者必須能夠使用 Tab 和方向鍵來瀏覽您的應用程式、使用空格鍵和 Enter 鍵來啟用 UI 元素,以及使用鍵盤快速鍵來存取命令。

設計良好的鍵盤 UI 是軟體協助工具的一個重要層面。它讓視障使用者或受到某種程度運動神經傷害的使用者能夠瀏覽應用程式並與應用程式的功能互動。這類使用者有可能無法使用滑鼠,因而必須仰賴像鍵盤增強功能工具、螢幕小鍵盤、螢幕放大機、螢幕助讀程式以及語音輸入公用程式這類協助技術。

最常見的鍵盤類型是與裝置連接的外接式硬體鍵盤。除了硬體鍵盤之外,Windows 8 還提供兩種軟體鍵盤:

    • Applies to Windows

    視窗:

    螢幕小鍵盤是視覺化的軟體鍵盤,可用來取代實體鍵盤,透過觸控、滑鼠、畫筆/手寫筆或其他指標裝置 (不需要觸控式螢幕) 來輸入資料。提供螢幕小鍵盤的用意是針對沒有實體鍵盤的系統,或者使用者因行動不便而無法使用傳統實體輸入裝置的情況。螢幕小鍵盤會模擬絕大部分的硬體鍵盤功能。

    螢幕小鍵盤

    • Applies to Windows

    視窗:

    觸控式鍵盤是視覺化的軟體鍵盤,使用觸控輸入來輸入文字。觸控式鍵盤不能取代螢幕小鍵盤,因為它只能輸入文字 (它不會模擬硬體鍵盤),而且只有文字欄位或其他可編輯的文字控制項得到焦點之後,才會顯示。

    附註  螢幕小鍵盤的優先順序高於觸控式鍵盤,如果顯示螢幕小鍵盤,就不會顯示觸控式鍵盤。

    以下是觸控式鍵盤的範例。第一個圖是預設配置,第二個是拇指配置 (不是所有語言都有提供)。

    預設配置的觸控式鍵盤

    拇指配置的觸控式鍵盤

鍵盤事件

硬體和觸控式鍵盤都有可能發生以下的鍵盤事件。

事件說明
KeyDown 按下按鍵時發生。
KeyUp 放開按鍵時發生。

 

鍵盤事件和焦點

您 UI 中的控制項只有在取得輸入焦點時才會產生鍵盤事件。個別控制項會在使用者直接按一下或點選配置上的控制項時取得焦點,或是在內容區域內使用 Tab 鍵進入 Tab 順序時取得焦點。

您也可以呼叫控制項的 Focus 方法來強制取得焦點。這種方式在實作快速鍵時很必要,因為 UI 載入時預設並沒有設定鍵盤焦點。如需詳細資訊,請參閱這個主題中後面的快速鍵範例

為了讓控制項接收輸入焦點,必須啟用控制項並顯示它,而且 IsTabStopHitTestVisible 屬性必須為 true。這是大多數控制項的預設狀態。當控制項取得輸入焦點時,它就可以引發和回應鍵盤輸入事件,如這個主題後面所述。處理 GotFocusLostFocus 事件也可以回應取得或失去焦點的控制項。

根據預設,控制項的 Tab 順序是依據它們在 XAML 上出現的順序。不過,使用 TabIndex 屬性就可以修改這個順序。如需詳細資訊,請參閱實作鍵盤協助工具

鍵盤事件處理常式

輸入事件處理常式實作一個提供下列資訊的委派:

  • 事件發送者。發送者會回報附加了事件處理常式的物件。
  • 事件資料。以鍵盤事件來說,該資料將會是 KeyRoutedEventArgs 的執行個體。處理常式的委派是 KeyEventHandler。對大多數處理常式案例來說,最相關的 KeyRoutedEventArgs 屬性是 Key,也有可能是 KeyStatus
  • OriginalSource。由於鍵盤事件是路由事件,因此事件資料會提供 OriginalSource。如果您是刻意讓物件透過物件樹反昇,有時 OriginalSource (而不是發送者) 就會成為較為重要的物件。不過這需要視您的設計而定。如需如何使用 OriginalSource 而非發送者的相關資訊,請參閱這個主題的<鍵盤路由事件>一節,或參閱事件與路由事件概觀

附加鍵盤事件處理常式

您可以為任何物件附加鍵盤事件處理函式,只要該事件是該物件的成員即可。這包含任何 UIElement 衍生類別。下列 XAML 範例示範如何為 Grid 附加 KeyUp 事件的處理常式。



<Grid KeyUp="Grid_KeyUp">
  ...
</Grid>


您也可以在程式碼中附加事件處理常式。如需詳細資訊,請參閱事件與路由事件概觀

定義鍵盤事件處理常式

下面的範例示範前面範例中附加的 KeyUp 事件處理常式的不完整事件處理常式定義。


void MyProject::MainPage::Grid_KeyUp(
  Platform::Object^ sender,
  Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
{//handling code here}

使用 KeyRoutedEventArgs

所有鍵盤事件都是使用 KeyRoutedEventArgs 代表事件資料,KeyRoutedEventArgs 包含下列屬性:

按鍵

如果按下按鍵,會引發 KeyDown 事件。同樣的,如果放開按鍵,會引發 KeyUp 事件。通常您接聽事件是為了處理特定的按鍵值。若要判斷按下或放開的是哪一個按鍵,請檢查事件資料中的 Key 值。Key 會傳回 VirtualKey 值。VirtualKey 列舉包括所有受支援的按鍵。

輔助按鍵

  • Applies to Windows

視窗:

輔助按鍵是使用者通常與其他按鍵一起按的按鍵,如 Ctrl 或 Shift。您的應用程式可以使用這些按鍵組合當作鍵盤快速鍵來叫用應用程式命令。

在您的 KeyDownKeyUp 事件處理常式中使用程式碼,即可偵測快速鍵組合。然後,您可以追蹤想了解的輔助按鍵按下狀態。當非輔助按鍵發生鍵盤事件時,您可以同時檢查輔助按鍵是否處於按下狀態。

附註  Alt 鍵以 VirtualKey.Menu 值表示。

快速鍵範例

  • Applies to Windows

視窗:

下面的範例示範如何實作快速鍵。在這個範例中,使用者可以使用「播放」、「暫停」以及「停止」按鈕或 Ctrl+P、Ctrl+A 以及 Ctrl+S 鍵盤快速鍵來控制媒體的播放。按鈕 XAML 使用工具提示以及按鈕標籤中的 AutomationProperties 屬性顯示捷徑。這個自我說明文件對於提高應用程式的可用性及協助性是很重要的。如需詳細資訊,請參閱實作鍵盤協助工具

另請注意,頁面載入時會將輸入焦點設給本身。如果沒有這個步驟,就沒有控制項會取得初始輸入焦點,而且除非使用者手動設定輸入焦點 (例如,按 Tab 鍵或按一下控制項),否則應用程式將無法引發輸入事件。


<Grid KeyDown="Grid_KeyDown">

  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>

  <MediaElement x:Name="DemoMovie" Source="xbox.wmv" 
    Width="500" Height="500" Margin="20" HorizontalAlignment="Center" />

  <StackPanel Grid.Row="1" Margin="10"
    Orientation="Horizontal" HorizontalAlignment="Center">

    <Button x:Name="PlayButton" Click="MediaButton_Click"
      ToolTipService.ToolTip="Shortcut key: Ctrl+P"
      AutomationProperties.AcceleratorKey="Control P">
      <TextBlock>Play</TextBlock>
    </Button>

    <Button x:Name="PauseButton" Click="MediaButton_Click"
      ToolTipService.ToolTip="Shortcut key: Ctrl+A" 
      AutomationProperties.AcceleratorKey="Control A">
      <TextBlock>Pause</TextBlock>
    </Button>

    <Button x:Name="StopButton" Click="MediaButton_Click"
      ToolTipService.ToolTip="Shortcut key: Ctrl+S" 
      AutomationProperties.AcceleratorKey="Control S">
      <TextBlock>Stop</TextBlock>
    </Button>

  </StackPanel>

</Grid>



//showing implementations but not header definitions
void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
{
    (void) e;    // Unused parameter
    this->Loaded+=ref new RoutedEventHandler(this,&MainPage::ProgrammaticFocus);
}
void MainPage::ProgrammaticFocus(Object^ sender, RoutedEventArgs^ e) {
    this->Focus(Windows::UI::Xaml::FocusState::Programmatic);
}

void KeyboardSupport::MainPage::MediaButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    FrameworkElement^ fe = safe_cast<FrameworkElement^>(sender);
    if (fe->Name == "PlayButton") {DemoMovie->Play();}
    if (fe->Name == "PauseButton") {DemoMovie->Pause();}
    if (fe->Name == "StopButton") {DemoMovie->Stop();}
}


void KeyboardSupport::MainPage::Grid_KeyDown(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
{
    if (e->Key == VirtualKey::Control) isCtrlKeyPressed = true;
}


void KeyboardSupport::MainPage::Grid_KeyUp(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
{
    if (e->Key == VirtualKey::Control) isCtrlKeyPressed = true;
    else if (isCtrlKeyPressed) {
        if (e->Key==VirtualKey::P) {
            DemoMovie->Play();
        }
        if (e->Key==VirtualKey::A) {DemoMovie->Pause();}
        if (e->Key==VirtualKey::S) {DemoMovie->Stop();}
    }
}


附註  在 XAML 中設定 AutomationProperties.AcceleratorKeyAutomationProperties.AccessKey 可提供字串資訊,其中記載用於叫用該特定動作的捷徑。Microsoft UI 自動化用戶端 (例如朗讀程式) 會擷取此資訊,通常直接提供給使用者。設定 AutomationProperties.AcceleratorKeyAutomationProperties.AccessKey 本身不會有任何動作。您還是需要附加 KeyDownKeyUp 事件的處理常式,才能實際在應用程式中實作鍵盤快速鍵行為。另外,也不會自動提供便捷鍵的底線文字裝飾。如果您希望在 UI 中顯示有底線的文字,必須以內嵌 Underline 格式明確的為助憶鍵中的特定鍵加上文字底線。

鍵盤路由事件

有一些特定事件是路由事件,包括 KeyDownKeyUp。路由事件使用事件反昇路由策略。反昇路由策略表示事件源自於子物件,並接著反昇路由到物件樹中相繼的父物件。這是處理相同事件並與相同事件資料互動的機會。

以下列 XAML 範例為例,它會處理一個 Canvas 和兩個 Button 物件的 KeyUp 事件。在這個情況下,如果在任一 Button 物件具有焦點時放開按鍵,則會引發 KeyUp 事件。接著,事件會反昇到父 Canvas


<StackPanel KeyUp="StackPanel_KeyUp">
  <Button Name="ButtonA" Content="Button A"/>
  <Button Name="ButtonB" Content="Button B"/>
  <TextBlock Name="statusTextBlock"/>
</StackPanel>


下面的範例示範如何實作前一個範例中對應的 XAML 內容的 KeyUp 事件處理常式。


void StackPanel_KeyUp(object sender, KeyRoutedEventArgs e)
{
    statusTextBlock.Text = String.Format(
        "The key {0} was pressed while focus was on {1}",
        e.Key.ToString(), (e.OriginalSource as FrameworkElement).Name);
}


請注意,前面處理常式中有用到 OriginalSource 屬性。這裡的 OriginalSource 會回報引發事件的物件。物件不可以是 StackPanel,因為 StackPanel 不是控制項而且不可以取得焦點。在StackPanel 內的兩個按鈕中,只有一個可能引發事件,但是是哪一個呢?如果您是在處理父物件上的事件,可以使用 OriginalSource 來辨別實際的事件來源物件。

事件資料中的 Handled 屬性

視您的事件處理策略而定,您可能會只想使用一個事件處理常式來應對反昇事件。例如,如果您有附加到其中一個 Button 控制項的特定 KeyUp 處理常式,該處理常式會先使用它來處理該事件。在這個情況下,您可能不想讓父面板也同時處理事件。這時,您可以在事件資料中使用 Handled 屬性。

使用路由事件資料類別中的 Handled 屬性是為了報告先前在事件路由上登錄的另一個處理常式已經執行。這會影響路由事件系統的行為。將事件處理常式中的 Handled 設成 true 時,該事件會停止路由而不會傳送給相繼的父元素。

AddHandler 和已處理的鍵盤事件

您可以使用一項特別的技術,以附加可以在已標示為處理過的事件上作用的處理常式。這項技術使用 AddHandler 方法來登錄處理常式,而不是使用 XAML 屬性或語言特定的語法新增處理常式 (例如 C# 中的 +=)。大致上,這項技術的限制在於 AddHandler API 是採用一個 RoutedEvent 類型的參數來識別相關的路由事件。並非所有路由事件都提供 RoutedEvent 識別項,因此這項考量也就影響到哪些路由事件仍然可以在 Handled 案例中處理。KeyDownKeyUp 事件在 UIElement 上已有路由事件識別項 (KeyDownEventKeyUpEvent)。不過,其他事件 (例如 TextBox.TextChanged) 並沒有路由事件識別項,因此也就不能與 AddHandler 技術搭配使用。

命令

少數 UI 元素提供命令功能的內建支援。命令功能在相關實作中使用輸入相關路由事件。它會叫用單一命令處理常式來處理相關的 UI 輸入,例如特定指標動作或特定快速鍵。

如果某個 UI 元素擁有命令功能,請考慮使用它的命令 API,而非任何個別輸入事件。如需詳細資訊,請參閱 ButtonBase.Command

您也可實作 ICommand 來封裝從一般事件處理常式叫用的命令功能。透過這種方式,即使沒有可用的 Command 屬性,您還是可以使用命令功能。

文字輸入和控制項

特定控制項會以它們自己的處理方式應對鍵盤事件。例如,TextBox 這個控制項的設計是擷取使用鍵盤輸入的文字,然後以視覺化方式呈現文字。它在自己的邏輯中使用 KeyUpKeyDown 來擷取按鍵輸入動作,然後如果文字真的變更了,就會引發它自己的 TextChanged 事件。

一般來說,您仍然可以將 KeyUpKeyDown 的處理常式加到 TextBox,或加到任何要用來處理文字輸入的相關控制項。不過,基於控制項本身的設計目的,控制項可能不會對透過按鍵事件導向它的所有按鍵值都提供回應。每個控制項都有它的特定行為。

例如,ButtonBase (Button 的基礎類別) 會處理 KeyUp,這樣它就可以檢查空格鍵或 Enter 鍵。ButtonBaseKeyUp 視為等同滑鼠左鍵,可以引發 Click 事件。事件的處理會在 ButtonBase 覆寫虛擬方法 OnKeyUp 時完成。在實作中,它會將 Handled 設定成 true。以空格鍵為例,結果是接聽按鍵事件的任何父按鈕,都不會收到自己的處理常式的已處理事件。

另一個範例是 TextBoxTextBox 並不將某些按鍵 (例如方向鍵) 視為文字,而是視為控制項 UI 特定的行為。TextBox 會將這些事件案例標示為已處理。

自訂控制項可以透過覆寫 OnKeyDown / OnKeyUp,以實作它們自己類似的按鍵事件覆寫行為。如果您的自訂控制項會處理特定的快速鍵,或具有類似於針對 TextBox 所述之情況的控制項或焦點行為,就應該將這個邏輯放入您自己的 OnKeyDown / OnKeyUp 覆寫中。

觸控式鍵盤

文字輸入控制項會自動支援觸控式鍵盤。當使用者使用觸控輸入將輸入焦點設為文字控制項時,觸控式鍵盤會自動出現。當輸入焦點不在文字控制項時,觸控式鍵盤就會隱藏起來。

當觸控式鍵盤出現時,它會自動定位您的 UI,以確保取得焦點的元素保持永遠可見。這可能會造成 UI 中其他重要的區域跑到螢幕外。不過,您可以停用預設行為,並在觸控式鍵盤出現時調整 UI。如需詳細資訊,請參閱回應螢幕小鍵盤外觀的範例

如果建立需要文字輸入但不是從標準輸入控制項衍生的自訂控制項,您可以實作正確的 UI 自動化控制項模式來加入對觸控式鍵盤的支援。如需詳細資訊,請參閱觸控式鍵盤範例

按下觸控式鍵盤上的按鍵,就像按下硬體鍵盤上的按鈕一樣,會引發 KeyDownKeyUp 事件。不過,觸控式鍵盤將不會引發 Ctrl+A、Ctrl+Z、Ctrl+X、Ctrl+C 以及 Ctrl+V 的輸入事件,因為它們是保留給輸入控制項的文字操作。

支援鍵盤互動的使用者經驗指導方針

以下為一些支援鍵盤互動的指導方針。

一般

    • Applies to Windows

    視窗:

    使用者必須能夠單獨使用硬體鍵盤或螢幕小鍵盤,完成應用程式支援的所有工作。

    附註  觸控式鍵盤僅適用於文字輸入,不適用於應用程式或系統命令。

  • 當應用程式啟動時,將起始鍵盤焦點設在使用者最先直覺 (或最有可能) 互動的元素上。通常,最適當的位置是應用程式的主要內容檢視,這樣使用者就能立即使用方向鍵捲動內容。如需將焦點設在特定控制項的詳細資訊,請參閱Focus
    • Applies to Windows

    視窗:

    確定 Tab 鍵和方向鍵能夠以邏輯順序在內容中移動。
  • 如果互動式 UI 預設未在定位順序中,請將這些互動式 UI 的 TabIndex 屬性設定成大於或等於 0 的值。設定 TabIndex 屬性很重要,因為螢幕助讀程式使用者就是使用 Tab 鍵與 UI 元素進行互動。
    • Applies to Windows

    視窗:

    使用方向鍵做為鍵盤快速鍵,以便在複合元素中的各個子元素之間瀏覽。如果樹狀檢視節點使用獨立的子元素來處理展開折疊以及節點啟動,請使用向左鍵或向右鍵,提供鍵盤展開折疊功能。
  • 確定可以用鍵盤叫用可按一下的每個 UI 元素。
    • Applies to Windows

    視窗:

    實作主應用程式功能的鍵盤快速鍵。(捷徑是一種按鍵組合,可讓使用者更有效率地存取應用程式功能,提高生產力)。

    便捷鍵是應用程式的 UI 元素捷徑。它包含 Alt 鍵和一個字母按鍵。

    「快速鍵」是應用程式命令的捷徑。您的應用程式可以包含準確對應到命令的 UI。快速鍵包含 Ctrl 鍵和一個字母按鍵。

    請為依賴螢幕助讀程式或其他輔助技術的使用者,提供一種便利的方法,讓他們找到應用程式的快速鍵。使用 AccessKey 屬性,在應用程式的 HTML 標記中宣告快速鍵,並透過工具提示、無障礙名稱、無障礙說明,或是其他螢幕上顯示的方式,讓使用者知道快速鍵。請記得在應用程式的說明內容中,詳細記載快速鍵。

    如需實作快速鍵的指引,請參閱《Windows 使用者體驗指導方針》中的快速鍵

    不要重新定義使用者預期在每個 Windows 市集應用程式看到的預設鍵盤快速鍵。如需完整清單,請參閱鍵盤快速鍵

硬體

查詢鍵盤裝置的功能 (KeyboardCapabilities),判斷是否有連接鍵盤,了解鍵盤硬體可以直接存取應用程式 UI 的什麼層面。如需查詢裝置功能的詳細資訊,請參閱快速入門:識別指標裝置

請設定鍵盤按鈕與應用程式中適當 UI (上一頁和下一頁按鈕) 的關聯。

視覺化回饋

  • 請只搭配鍵盤互動使用焦點矩形。如果使用者初始化觸控互動,讓鍵盤 UI 逐漸淡出。 這可以讓 UI 保持整齊、不凌亂。
  • 如果元素不支援互動 (例如靜態文字),請勿顯示視覺化回饋。
  • 如果所有元素均代表相同的輸入目標,請同時顯示視覺化回饋。
  • 提供模擬觸控式操作 (例如移動瀏覽、旋轉、縮放等等) 的螢幕上按鈕 (例如 + 和 -) 做為提示。

如需視覺化回饋的詳細一般指導方針,請參閱視覺化回饋的指導方針

相關主題

概念
回應使用者互動
快速入門:新增 HTML 控制項和處理事件
實作鍵盤協助工具
使用 C++、C# 或 Visual Basic 的 Windows 市集應用程式中的協助工具
顯示和編輯文字
輸入主機管理員和觸控式鍵盤

 

 

顯示:
© 2014 Microsoft