2010-03-04 136 views
33

我有一個使用MVVM模式的WPF應用程序。連接虛擬機的按鈕非常簡單,因爲它們實現了ICommand。我有一個類似的上下文菜單。下一步是爲上下文菜單創建快捷鍵。我無法弄清楚如何讓快捷鍵調用命令。這裏有一個例子:將WPF快捷鍵綁定到ViewModel中的命令

<MenuItem Header="Update" Command="{Binding btnUpdate}" > 
    <MenuItem.Icon> 
     <Image Source="/Images/Update.png" 
       Width="16" 
       Height="16" /> 
     </MenuItem.Icon> 
    </MenuItem> 

現在我已經添加了這個:

<Window.InputBindings> 
    <KeyBinding Key="U" 
       Modifiers="Control" 
       Command="{Binding btnUpdate}" /> 
</Window.InputBindings> 

嘗試和快捷鍵連接到相同的結合,但這不起作用。錯誤是:

錯誤169無法在'KeyBinding'類型的'Command'屬性上設置'綁定'。 '綁定'只能在DependencyObject的DependencyProperty上設置。

是不是有辦法將這個事件連接到命令?我無法弄清楚這一點。

在此先感謝!

比爾

+0

我要指出,我使用的約什 - 史密斯的RelayCommand爲好。 – 2010-03-04 21:54:18

回答

25

我寫了一個custom markup extension「綁定」 InputBindings的命令,可用於幾乎像一個真正的約束力:

<UserControl.InputBindings> 
    <KeyBinding Modifiers="Control" 
       Key="E" 
       Command="{input:CommandBinding EditCommand}"/> 
</UserControl.InputBindings> 

注意,此標記擴展使用私有反映,因此它可以僅在您的應用程序完全信任時才能使用...

另一種選擇是使用CommandReference類。它可以在可用的MVVM工具包here中找到。這可能是一種更清潔的方法,但使用起來更復雜一些。

注意,在WPF 4,InputBinding.CommandInputBinding.CommandParameterInputBinding.CommandTarget屬性是依賴屬性,所以它們能正常

+0

優秀!這正是我正在尋找的。謝謝!! – 2010-03-06 15:20:22

+0

我遵循WPF MVVM Docs中的exs--很好的例子!正是我想要做的。不幸的是,上下文菜單項工作正常,但快捷鍵不起作用。我甚至無法弄清楚,因爲我按下快捷鍵時沒有任何反應。 – 2010-03-07 00:13:16

+0

難道是我試圖在ContextMenu上的快捷鍵上使用這些而不是標準菜單嗎? – 2010-03-07 00:16:55

0

束縛用於結合WPF快捷鍵視圖模型的一個命令屬性的另一種方法中示出WPF Application Framework (WAF)項目的ShortcutKey示例。

+0

謝謝......我需要一些時間來研究它(意思是我現在沒有太多時間,但我已經提高了,因爲鏈接看起來非常有用(不僅因爲我的問題) – 2012-08-08 09:03:36

8

我同意在XAML中這樣做是理想的,但爲了完整起見,您還可以在代碼中添加綁定。如果您在構造函數中做到這一點,只要確定它是調用InitializeComponent()

InputBindings.Add(new KeyBinding(btnUpdate, new KeyGesture(Key.U, ModifierKeys.Control)); 
+0

+1此方法允許我將它放到我的視圖中,因爲我需要的功能只能用於UI元素 – CaptainBli 2014-02-04 16:02:57

+2

但是,這綁定了一個按鈕控件,'btnUpdate'到快捷鍵Ctrl-U,而不是像Michel Keijzers的XAML那樣的命令。 – ProfK 2014-10-23 12:53:07

+1

I在回答這是試圖綁定到一種叫「btnUpdate」。 – 2014-10-29 18:06:22

30

下面的代碼後,可用於快捷鍵直接綁定到一個命令:

<Window.InputBindings> 
    <KeyBinding Command="{Binding Path=NameOfYourCommand}" 
       Key="O" 
       Modifiers="Control"/> 
</Window.InputBindings> 

添加此在視圖的XAML代碼中的Window.Resources之後。

+15

此方法適用於.NET 4了。 – 2012-03-21 20:32:46

+3

呀不知道OP的問題但是這個工作正常(我使用MVVM燈) – GONeale 2012-08-08 05:33:32

+6

他特別說這不起作用,並且選定的答案解釋了原因:H e不使用WPF4。不知道爲什麼你發佈他的確切代碼作爲「答案」 – aaronburro 2012-09-13 13:56:18

0

已經能夠在DataGrid級別添加Keybinding。就像這樣:

的XAML:

<DataGrid 
        AutoGenerateColumns="False" 
        ItemsSource="{Binding YourCollection}"       
        CanUserAddRows="False"       
        HeadersVisibility="Column" 
        CanUserDeleteRows="False" 
        CanUserSortColumns="True" 
        CanUserResizeRows="False" 
        CanUserResizeColumns="False"      
        SelectedItem="{Binding YourSelectedItem}" 
        SelectionMode="Single" 
        SelectionUnit="FullRow" 
        > 
       <DataGrid.ContextMenu> 
        <ContextMenu> 
         **<MenuItem Header="Delete" InputGestureText="Del" Command="{Binding DeleteCommand}">** 
         </MenuItem> 
        </ContextMenu> 
       </DataGrid.ContextMenu> 
       **<DataGrid.InputBindings> 
        <KeyBinding Key="Delete" Command="{Binding DeleteCommand}" CommandParameter="Delete"/>** 
       </DataGrid.InputBindings> 
       <DataGrid.Columns> 
        <DataGridTextColumn Header="Column Header" Binding="{Binding YourColumn}" IsReadOnly="True" /> 
       </DataGrid.Columns> 
</DataGrid> 

視圖模型:

public ICommand DeleteCommand 
      { 
       get 
       { 
        return new DelegateCommand(ExecuteCommand, CanExecute); 
       } 
      } 

    private void ExecuteCommand() 
{ 
// your code to delete here. 
    YourCollection.Remove(YourSelectedItem); 
} 

private void CanExecute() 
{ 
// logic to check if the delete command can execute. 
    return YourSelectedItem != null ; 
} 
相關問題