views:

569

answers:

4

I have an tabControl1 in my form with three TabPages named TabPage1, TabPage2 and TabPage3.

When TabPage 2 has focus I need to raise an key event (arrow keys for navigation). This event should not be raised in the other TabPages.

Anybody know how?

+2  A: 

On Selected event handler you can cast the sender to the proper control and check for it's name. If the event is generated from TabPage2 you can fire the key event.

Something like this

private void TabPage_Selected(object sender, EventArgs e)
{
  TabPage source = sender as TabPage;
  if(source.Name.equals("TabPage2"))
    //Do whatever...
}
mamoo
private void tabControl1_KeyDown(object sender, KeyEventArgs e) { MessageBox.Show("Key pressed"); }Should this give me an Messagebox when a key is pressed and when this tabcontrol has focus?Mamoo : your code didn't work for some reason
Qrew
Probably the event handler name and/or TabPage control name are not the same. Anyway things are a bit unclear after this comment...The expected behaviour is: Show a message (or do something else...) if a key is pressed AND the focus is on a certain TabPage?
mamoo
I think the problem is that the tab Page can't have focus (there is no object on the page that can be selected, just a bunch of labels). We must check if the correct tab is choosed and then dosomething when keys are pressed
Qrew
+1  A: 

You'll need to derive your own control from TabControl so that you can intercept the arrow keys and generate an event. Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form.

using System;
using System.Windows.Forms;

class MyTabControl : TabControl {
  public event EventHandler<KeyEventArgs> ArrowKeys;

  protected void OnArrowKeys(KeyEventArgs e) {
    EventHandler<KeyEventArgs> handler = ArrowKeys;
    if (handler != null) handler(this, e);
  }
  protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
    if (keyData == Keys.Up || keyData == Keys.Down || keyData == Keys.Left || keyData == Keys.Right) {
      var e = new KeyEventArgs(keyData);
      OnArrowKeys(e);
      if (e.Handled) return true;
    }
    return base.ProcessCmdKey(ref msg, keyData);
  }
}

Sample usage in a form:

private void myTabControl1_ArrowKeys(object sender, KeyEventArgs e) {
  if (myTabControl1.SelectedIndex == 1) {
    // Do something with e.KeyData
    //...
    e.Handled = true;
  }
}
Hans Passant
I can't manage it to work. It just switches between the tabs when pressing left/right arrow.
Qrew
Where's the focus? Is it not on a control inside the tab page?
Hans Passant
The tab page has only labels. I think that's the problem. I want to navigate to the different tabs with F2+F3+F4 keys and then when Tab Page2 has been choosed i need to take care of the arrow keys becase the different labels are number and should change color to see which label is "selected" (nothing is selected but only visualy). The labels are a bunch of numbers and I need to change the individual labels(numbers) with pageup and pagedown key.
Qrew
The posted code works fine when the tab page contains only labels. Did you actually wire up the ArrowKeys event? Just pasting the code doesn't work. In the Properties window, click the lightning bolt icon then double-click ArrowKeys.
Hans Passant
A: 

I did this in VB .NET, I can post it in C# if you really need it but this should show you how to handle the catching of the event.

Public Class Form1

    'give a variable as a TabPage here so we know which one is selected(in focus)
    Dim selectedPage As TabPage = TabPage1

    'If a key is pressed when the tab control has focus, it checks to see if it is the right tab page
    'and then show a message box(for demonstration)
    Private Sub TabControl1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TabControl1.KeyDown
        'The IF Not is to basically catch any odd happening that might occur if a key stroke gets passed with
        'no selected tab page
        If Not selectedPage Is Nothing Then
            'If the tabpage is TabPage2
            If selectedPage.Name = "TabPage2" Then
                MessageBox.Show("Key Pressed")
            End If
        End If
    End Sub

    'This handles the actual chaning of the tab pages
    Private Sub TabControl1_Selected(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TabControlEventArgs) Handles TabControl1.Selected
        selectedPage = TabControl1.SelectedTab
    End Sub

And now you just need to use the actual key presses.

Michael Sarchet

msarchet
A: 

protected override bool ProcessCmdKey(ref Message m, Keys keyData)
{
bool blnProcess = false;
if (keyData == Keys.Left)
{
blnProcess = true;
MessageBox.Show("Key left");
if (myTabControl1.SelectedIndex == 1)
MessageBox.Show("inside");
}

This code seems to work So when I have selected the tabPage2 a Messagebox tells me "inside" when i press left arrow key.

Probalby not the correct thing to do thing but atleast it works for now...

Qrew