Search code examples
c#wpfxamlmvvmdatacontext

How to set the DataContext of a KeyBinding to a specific ViewModel?


This seems like such a basic question but after hours of searching around and not figuring out what I'm doing wrong I decided it's time to ask for help!

I'm new to WPF and the MVVM pattern, but am trying to create an application that has several windows you can navigate through by clicking buttons. This is accomplished by having the app window display UserControls using DataTemplates, so there's no content currently shared between pages (though there will be once I create the navigation area). Here's what the XAML looks like for the main window, with there currently only being one page in the application:

<Window x:Class="WPF_Application.ApplicationView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WPF_Application"
    Title="ApplicationView" Height="300" Width="300" WindowStartupLocation="CenterScreen" WindowState="Maximized">

<Window.Resources>
    <DataTemplate DataType="{x:Type local:LoginMenuViewModel}">
        <local:LoginMenuView />
    </DataTemplate>
</Window.Resources>


<DockPanel>
    <ContentControl
        Content="{Binding CurrentPageViewModel}" />
</DockPanel>

Now what I'd like to do is add a KeyBinding that reacts to the escape button being pressed. When this is done "LogoutCommand" should fire in the LoginMenuViewModel. I'm stuck getting the keybinding to trigger any commands within LoginMenuViewModel, and I've figured it's probably because the DataContext needs to be set to reference LoginMenuViewModel. For the life of me I can't get this to work.

Am I going about application-wide commands completely the wrong way? Is there some super simple fix that will make me smack my forehead in shame? Any insight is appreciated!


Solution

  • I do not know your ViewModel code, so it is not easy to give you details hints. First of all, if your are using MVVM, you should have your own implementation of ICommand interface. You can find here the most common one (and a simple MVVM tutorial too).

    After you have your own command class, your ViewModel should expose your LogoutCommand:

    public class ViewModel
    {
        /* ... */
    
        public ICommand LogoutCommand
        {
            get
            {
                return /* your command */
            }
        }
    
        /* ... */
    }
    

    In your code behind you will set: DataContext = new ViewModel(); and at this point you can declare the KeyBindings that you need:

    <Window.InputBindings>
        <KeyBinding Key="Escape" Command="{Binding Path=LogoutCommand, Mode=OneWay}" />
    </Window.InputBindings>
    

    In this way when the Window is active and the user press the "Esc" key, your LogoutCommand is executed.

    This is a brief summary that I hope will guide you in deepening the MVVM and its command system.