1

I have two datagridviews on my form. I have one (dgv1) that I edit the data in and one (dgv2) that is used for viewing only (catching click actions). For example, I might be editing a cell (text) in dgv1 and need to double click on a row in dgv2 to put the contents into dgv1 (similar to a quick copy/paste). Currently I have to use the right mouse double click event on dgv2 because if at any time I left click or left double click the focus will move from dgv1 to dgv2 and stop editing the dgv1 cell I'm working on.

I want to see if it's possible to be able to do exactly what I'm doing by double right clicking on dgv2 with the left mouse click button?

The only thing I could come up with is to try and find a way to disable the left mouse click event but I was hoping to basicly just make it "not respond" like it does when you double RIGHT click on the cell/row.

Ideas?

Edit: Example of dgv2 CellMouseDoubleClick event

private void dgv2_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.Button != MouseButtons.Right) return;

    DataGridView dgvSrc = (DataGridView)sender;
    DataGridView dgvDest = dgv1;

    DataGridViewCell cellSrc = dgvSrc.Rows[e.RowIndex].Cells["dgv2VariableName"];

    foreach (DataGridViewCell cell in dgvDest.SelectedCells)
    {
        if (cell.IsInEditMode && dgvDest.CurrentCell.EditType == typeof(DataGridViewTextBoxEditingControl))
        {
            //Target inserting the variable in the current selected edited area inside the textbox
            TextBox editBox = (TextBox)dgvDest.EditingControl;

            int selStartPos = editBox.SelectionStart;
            int selEndPos = selStartPos + editBox.SelectionLength;

            editBox.Text = editBox.Text.Substring(0, selStartPos) + cellSrc.Value.ToString() + editBox.Text.Substring(selEndPos);
            editBox.SelectionStart = selStartPos + cellSrc.Value.ToString().Length;
        }
        else
        {
            //Just override the entire cell
            cell.Value = cellSrc.Value;
        }
    }
}
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398
Arvo Bowen
  • 4,524
  • 6
  • 51
  • 109
  • Will you need to remember the insertion point in dgv1 or will you always replace the whole cell content? Also: Will interrupting the editing cause validation errors? – TaW Oct 19 '16 at 21:46
  • @TaW Both, I have added an example in the question. ;) Interrupting will not be a problem, I could do something like handle the onclick event on dgv2 and then just set focus back to dgv1 selecting the cell and start the edit again then place the selection index at the last known position in the text edit box... I was just hoping there was a simpler way. If there is not I will just leave it working on the right click button... I was just hoping I could do the same thing with the left click button. – Arvo Bowen Oct 19 '16 at 22:25
  • I doubt it can be done, but I have been wrong before ;-) – TaW Oct 19 '16 at 22:35
  • @TaW It can be done ;) – Reza Aghaei Oct 31 '16 at 15:35

1 Answers1

2

You can make your DataGridView non-selectable and also make it read-only. Then when user double click on its cells, it doesn't steal focus from the focused control.

To make it read only, it's enough to set its ReadOnly property to true. To make in non-selectable, you can derive from DataGridView and in constructor, make in non-selectable:

SetStyle(ControlStyles.Selectable, false);

Note

Since SetStyle is prottected, you can not use it outside of your control. But you can call it using reflection. Since it's a useful method, you can create an extension method like what I used here to simulate an on-screen keyboard. Then you can use it against all controls. Here is the settings which I used for second DataGridView:

this.dataGridView2.SetStyle(ControlStyles.Selectable, false);
this.dataGridView2.ReadOnly = true;

And here is the extension method which I used to expose SetStyle:

public static class Extensions
{
    public static void SetStyle(this Control control, ControlStyles flags, bool value)
    {
        Type type = control.GetType();
        BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
        MethodInfo method = type.GetMethod("SetStyle", bindingFlags);
        if (method != null)
        {
            object[] param = { flags, value };
            method.Invoke(control, param);
        }
    }
}
Community
  • 1
  • 1
Reza Aghaei
  • 120,393
  • 18
  • 203
  • 398