Question

I've implemented this modified TabItem to add a "Close" button to each tab of a WPF TabControl:

http://www.codeproject.com/Articles/281402/Closable-TabItem-in-WPF

Everything works very well, but I cannot figure out for the life of me how to add a KeyBinding for Ctrl+W to serve as an alternate way of closing tabs. I've tried adding to the CloseTab.cs class as well as my main window class with no luck.

I was using this for reference:

Keyboard shortcuts in WPF

...but I don't really understand how to add the shortcut.

Was it helpful?

Solution

I haven't really tested this, but maybe instead of using InputGestures (since you can't get that to work I guess), maybe you can alternatively bind to a command and check the Keyboard for currently pressed keys?

So inside the xaml where the ClosableTabItem is defined:

(you'll need to add a reference to System.Windows.Interactivity)

xmlns:local="clr-namespace:TestDemo"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

<local:ClosableTabItem Header="TabItem 1">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="KeyDown">
            <i:InvokeCommandAction Command="{Binding KeyDownCommand}"/>
         </i:EventTrigger>
     </i:Interaction.Triggers>
</local:ClosableTabItem>

Then the command:

private RelayCommand _KeyDownCommand;
public ICommand KeyDownCommand
{
    get
    {
        if (this._KeyDownCommand == null)
            this._KeyDownCommand = new RelayCommand(param => this.CheckKeysDown());

        return this._KeyDownCommand;
    }
}

And the method:

private void CheckKeysDown()
{
    if (Keyboard.IsKeyDown(Key.W) && ((Keyboard.Modifiers & ModifierKeys.Control) > 0))
    {
        // Ctrl + W was pressed
    }
}

EDIT: To expand on my answer, I found this pretty useful implementation as well: http://joyfulwpf.blogspot.com/2009/05/mvvm-commandreference-and-keybinding.html

You can use CommandReference in the above link's implementation to execute when a KeyBinding is satisfied!

EDIT2: To do this in the code behind (for dynamically added tab items):

System.Windows.Interactivity.EventTrigger trigger = 
    new System.Windows.Interactivity.EventTrigger();
trigger.EventName = "KeyDown";
System.Windows.Interactivity.InvokeCommandAction keyDownAction =
    new System.Windows.Interactivity.InvokeCommandAction();
keyDownAction.Command = KeyDownCommand;
trigger.Actions.Add(keyDownAction);
trigger.Attach(yourTabItem);

EDIT3: Ok, I just got the code myself and played around to figure out a fix for you. The way the ClosableTabItem class removes the tab is with the command StateChange. And I just added a KeyBinding to a tab item I made in the code behind and it worked.

So I did this:

ClosableTabItem myTab = new ClosableTabItem();
myTab.InputBindings.Add(new KeyBinding(ClosableTabItem.StateChange, Key.W, ModifierKeys.Control));

So when you dynamically create your tabs, add this input binding above and have it hook up to the StateChange command. You might have to click the tab or tab area to get it in focus for the key binding to work. I noticed that during my testing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top