views:

2373

answers:

3

I have a form with a datagridview and when user start entering value for first cell in first row , , can also press f2 which submit that value , but i cant access cell value unless user hit tab and go to another cell

following is my code for accessing cell value when f2 is hit

 protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        var key = new KeyEventArgs(keyData);

        ShortcutKey(this, key);

        return base.ProcessCmdKey(ref msg, keyData);
    }


    protected virtual void ShortcutKey(object sender, KeyEventArgs key)
    {
        switch (key.KeyCode)
        {
            case Keys.F2:
                MessageBox.Show(dataGridView1.SelectedCells[0].Value.ToString());
                break;
        }
    }

dataGridView1.SelectedCells[0].Value returns null

A: 

There is an OnKeyDown handler for the DataGridViewCell:

http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridviewcell.onkeydown.aspx

However the only problem is that you are going to have to create your own custom cell based of DataGridViewTextBoxCell to get the intended functionality. Because there is no event exposed for this handler.

Nick Berardi
+1  A: 

How about doing something like this instead. Hook into the DataGridView's "EditingControlShowing" event and capture the F2 there. Some code:

public partial class Form1 : Form
{
    private DataTable table;
    public Form1()
    {
        InitializeComponent();
        this.dataGridView1.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(HandleEditingControlShowing);
        this.table = new DataTable();
        table.Columns.Add("Column");
        table.Rows.Add("Row 1");
        this.dataGridView1.DataSource = table;
    }


    private void HandleEditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
    {
        var ctl = e.Control as DataGridViewTextBoxEditingControl;
        if (ctl == null)
        {
            return;
        }

        ctl.KeyDown -= ctl_KeyDown;
        ctl.KeyDown += new KeyEventHandler(ctl_KeyDown);

    }

    private void ctl_KeyDown(object sender, KeyEventArgs e)
    {
        var box = sender as TextBox;
        if (box == null)
        {
            return;
        }

        if (e.KeyCode == Keys.F2)
        {
            this.dataGridView1.EndEdit();
            MessageBox.Show(box.Text);
        }
    }

}

The idea is simple, you hook into the EditingControlShowing event. Every time a cell enters edit mode, that gets fired. The cool thing is, it exposes the actual underlying control and you can cast it to the actual winforms control, and hook into all it's events as you normally would.

BFree
A: 

@BFree thanks your code inspired me ;) why not just calling this.dataGridView1.EndEdit(); before MessageBox.Show(dataGridView1.SelectedCells[0].Value.ToString());

this code works just fine :

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        var key = new KeyEventArgs(keyData);

        ShortcutKey(this, key);

        return base.ProcessCmdKey(ref msg, keyData);
    }


    protected virtual void ShortcutKey(object sender, KeyEventArgs key)
    {
        switch (key.KeyCode)
        {
            case Keys.F2:
dataGridView1.EndEdit();
                MessageBox.Show(dataGridView1.SelectedCells[0].Value.ToString());
                break;
        }
    }
Adinochestva