2013-07-09 51 views
6

問題:如何在按下並釋放Alt鍵後退出鍵盤熱鍵模式?在辦公室ESC的作品,在WPF中沒有。需要能夠退出Alt鍵下劃線模式,可能用ESC鍵

詳細信息:我在WPF應用程序中有各種Label元素。

<StackPanel> 
    <Label Grid.Column="0" VerticalAlignment="Center" Content="_Textbox 1" Target="textbox1" /> 
    <TextBox x:Name="textbox1" Width="50" /> 
    <Label Grid.Column="0" VerticalAlignment="Center" Content="T_extbox 2" Target="textbox2" /> 
    <TextBox x:Name="textbox2" Width="50" /> 
</StackPanel> 

當我按下並釋放AltP停留下劃線,然後我可以分別按P鍵和標籤需要它的行動。這與Word 2013和記事本的工作方式相同,因爲您不必同時按AltP

在哪裏WPF不同是我不能按ESC鍵停止下劃線並停止自動導航到Label控件。我看到擺脫鍵盤導航模式的唯一方法是使用鼠標並在某處點擊,從而擊敗了鍵盤導航的目標。

+3

實際上,記事本和Word 2013的行爲有細微差別。帶有熱鍵的控制器位於一個'Menu'中,只要按下Alt鍵,您就可以看到他們獲得焦點,文本區脫字符號會丟失,然後'Esc'將焦點返回到'TextBox'清除「_」。現在在你的示例代碼中,如果你把兩個'標籤'或者甚至一個放在'

'內,然後按下Alt鍵,你會得到與Word或記事本相同的行爲。沒有菜單,沒有控制想要採取中間焦點。 – Viv

回答

0

添加到我原來的評論

居然還有記事本和Word 2013的行爲稍有差異。帶有熱鍵的控件位於一個菜單中,只要按下Alt鍵就可以獲得焦點,並且您可以看到它們獲得焦點,文本區脫字符號將丟失,然後Esc將焦點返回到TextBox,同時清除「_」。現在在示例代碼中,如果您將兩個Label或甚至一個標籤放入a中,然後按Alt,則您將獲得與Word或記事本相同的行爲。沒有菜單,沒有控制想要採取中間焦點。

這只是似乎是一個問題,即Menu獲得延期的重點來處理這些熱鍵在它自己的FocusManager.IsFocusScope

MSDN另一個片段:

下面的方案說明了如何鍵盤焦點和邏輯焦點變化有一個文本框,並具有菜單項的菜單窗口中的Windows Presentation Foundation(WPF)應用程序。當鍵盤焦點從TextBox更改爲MenuItem時,TextBox會損失鍵盤焦點,但會保留Window焦點範圍的邏輯焦點。 MenuItem獲取鍵盤焦點並獲取菜單焦點範圍的邏輯焦點。當鍵盤焦點返回到根窗口時,具有邏輯焦點的窗口焦點範圍中的元素將獲得鍵盤焦點,在本例中爲TextBox。 TextBox現在具有鍵盤焦點和邏輯焦點。 MenuItem失去鍵盤焦點,但保留了菜單焦點範圍的邏輯焦點。

解決方案:

如果你只是無法忍受的事實,你由Menu規定的分組要求的限制,實現熱鍵功能,你可以這樣做:

<Grid Margin="25"> 
    <Grid.RowDefinitions> 
    <RowDefinition Height="Auto" /> 
    <RowDefinition Height="15" /> 
    <RowDefinition Height="Auto" /> 
    <RowDefinition Height="*" /> 
    <RowDefinition Height="Auto" /> 
    </Grid.RowDefinitions> 
    <Grid.ColumnDefinitions> 
    <ColumnDefinition Width="Auto" /> 
    <ColumnDefinition Width="*" /> 
    <ColumnDefinition Width="*" /> 
    </Grid.ColumnDefinitions> 
    <!-- cannot use Visibility="Collapsed" or "Hidden" on the Menu to make it take focus on Alt press --> 
    <Menu Width="0" 
     Height="0"> 
    <Label x:Name="label1" 
      Content="_Textbox 1" 
      Target="{Binding ElementName=textbox1}" /> 
    <Label x:Name="label2" 
      Content="T_extbox 2" 
      Target="{Binding ElementName=textbox2}" /> 
    <Label x:Name="label3" 
      Content="Another Loose Label to Link Text_Box 1" 
      Target="{Binding ElementName=textbox1}" /> 
    </Menu> 
    <Label Grid.Row="0" 
      Grid.Column="0" 
      Content="{Binding ElementName=label1, 
          Path=Content}" /> 
    <TextBox x:Name="textbox1" 
      Grid.Row="0" 
      Grid.Column="1" 
      Grid.ColumnSpan="2" 
      Margin="15 0 0 0" 
      VerticalAlignment="Center" /> 
    <Label Grid.Row="2" 
      Grid.Column="0" 
      Content="{Binding ElementName=label2, 
          Path=Content}" /> 
    <TextBox x:Name="textbox2" 
      Grid.Row="2" 
      Grid.Column="1" 
      Grid.ColumnSpan="2" 
      Margin="15 0 0 0" 
      VerticalAlignment="Center" /> 
    <Rectangle Grid.Row="3" 
       Grid.RowSpan="2" 
       Grid.Column="1" 
       Margin="10" 
       Fill="Tomato" /> 
    <Label Grid.Row="4" 
      Grid.Column="2" 
      Content="{Binding ElementName=label3, 
          Path=Content}" /> 
</Grid> 

所以在這種設置中,我們不使用任何自定義Style的任何控件的。我們幾乎創造一個新的頂級Menu和所有所需的熱鍵Label加's到它,並設置它的寬度和高度爲0

因此,在實際可見Grid佈局,我們可以定位可見Label的我們選擇的任何地方,避免代碼重複,在爲每個Label指定Label.Content兩次(一旦在菜單中,然後在實際佈局中),我們使用綁定從菜單中相應的標籤中獲取可視標籤的內容。

更新

回覆OP的評論:

我不知道這會在我的應用是可行的。我在整個應用程序中都有熱鍵,其中一些是屏幕上重複的。實施這種解決方法是不可維護的。

嗯,我沒有看到重複或有什麼東西會對這個tbh產生任何影響。

  • 如果你有多個重複的熱鍵的Window的,則定義爲Content這些重複的項目是在XAML中String資源或者你可以參考的.resx無處不在你需要它它。
  • 可維護 - 你沒有什麼特別的可維護性。您的佈局不受影響,您不受任何限制。如果有任何東西你可以坐在隱藏在每個Window的頂層的<Menu>中定義該Window的熱鍵,並且在該窗口內,任何需要該功能的控件將綁定到相應的Menu子項。我認爲它將Window中的熱鍵範圍統一在一個地方,而不是在多個不同的地方。

最後,我不是試圖強加這種方法在你身上,它歸結爲你的個人喜好。如果你不舒服,那麼你可以得到你的的分類,並自己實現延遲焦點的功能,或者提出一個微軟錯誤,看他們是否可以爲你解決它,或找到一個替代解決方案或放開熱點 - 鍵功能。

+0

你絕對是在這裏的東西。這個代碼的小故障是鍵盤快捷鍵只適用於在XAML中定義的第一個標籤。如果您顛倒標籤的順序,則第二個快捷方式開始工作。在這個偉大的努力! –

+0

@KevinKalitowski哦,我確實錯過了那一點。問題是,當按下Alt時,第一個聲明的'Menu'獲得延遲焦點,因此只有Hotkey在那個'Menu'的子節點中響應。在原始樣式中,每個'Label'都被包裝在一個單獨的'Menu'中,因此導致只有一個HotKey基於哪個標籤被首先聲明的問題。我調整了在菜單上應用的樣式,而不是標籤的樣式,因此要求在**一個**菜單中添加所有'標籤'作爲子標籤,以允許這兩個熱鍵的功能。更新我的答案,似乎工作正常。 – Viv

+0

@KevinKalitowski我還添加了一種替代方法,我們可以跳過定義任何自定義'樣式',並使用單獨的菜單作爲所有熱鍵的容器。這種方法解決了這個問題,即要求所有熱鍵Label都駐留在相同的菜單中,因爲我們得到了單獨的菜單處理,該需求在視覺上保持隱藏狀態,允許用戶根據自己的需要佈置UI。 – Viv