0

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.

Community
  • 1
  • 1
CXL
  • 1,094
  • 2
  • 15
  • 38

1 Answers1

1

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.

ryrich
  • 2,164
  • 16
  • 24
  • This might be a stupid question, but how do I add the Interaction.Triggers to my custom TabItem when I'm creating the tabs dynamically in my code? – CXL Mar 23 '14 at 16:48
  • @ClairelyClaire - try out my Edit2 and see if that works for you :) – ryrich Mar 23 '14 at 18:02
  • Thanks for your help! RelayCommmand doesn't seem to exist, however. I found what appears to be the class used in the MSDN article about RelayCommmand, but nothing happens... – CXL Mar 23 '14 at 21:38
  • @ClairelyClaire Ok, check out EDIT3 haha. – ryrich Mar 23 '14 at 23:08
  • Thank you! That worked perfectly, and with only one line of code, no less! I'm still VERY new to WPF, so I really appreciate the help. – CXL Mar 24 '14 at 13:13